mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-04-18 18:40:34 +08:00
New LaF
This commit is contained in:
parent
f4d148b042
commit
d1c4dee7f7
@ -4,6 +4,8 @@ jdk:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_install:
|
||||
- chmod +x gradlew
|
||||
before_deploy:
|
||||
- git config --global user.email ${GITHUB_EMAIL}
|
||||
- git config --global user.name ${GITHUB_NAME}
|
||||
@ -14,8 +16,7 @@ deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: KxGIpE83MsgSdWNwCyqgIKJevZgLAef3hpBEVZjqZ09mA3JjQzWCbVFEfWpv8yRqe8ue7YF0aH7YoWuqOiE9q93Qsvv3GRtVcnZqZiGZbCZer1ShtqcjSseMvsw66dtHNcdK6onHna+OrCh2TQjxE2tKMf3CPCP9K2RI6dYOTyYUWmiOmiYQfcd2MEGSRXdnCGi8nf5oBZOYfHforRH3QYJXA7AxI+I9xaEWimFKs1c73sE1pypIGw5rlc+tiKuG8f5QoMeEOy+D30Qe3Vlre13RTi73r6GVt1ZoRpAwlNLEgjD393V1mxGd9wYNBMRKIZ/dfvIAN4m/jltVpgSyuCiUj3sjNs39HV8Jk0ki6RoSoAsjIyWHWfag946sk5wuBjnIZajlQhpGoc94ml8ujxOqP0npQT8azm3CwkAmBx0cxQ09Td9WPREk9BL4bWZrp5t50PsB9SZHPV2ET98QQH6+ArldONYWDTNZMJ2Lc0s6rFZoInq2px1srbR7Cxq2rNsVRp15UFvQp5xueONXz68/wFet6Gbm2ob8TGKm1bQOh5MRO/fq+fkrIIjoD6ztlRaO3xtePXlyEbnJmyxXOdA+Rd9WFXsT9gzjKtlxQjdHZNnI0YiEjR2qvHIWguAQtuV4pydWi8VtlBQ2gT37CpF4ApfC6jTfMsEwqZZ29YM=
|
||||
file:
|
||||
- HMCL/build/libs
|
||||
file: HMCL/build/libs
|
||||
on:
|
||||
repo: huanghongxun/HMCL
|
||||
script: "bash ./gradlew clean build --stacktrace"
|
||||
|
@ -41,7 +41,7 @@ if (buildnumber == null)
|
||||
|
||||
def versionroot = System.getenv("VERSION_ROOT")
|
||||
if (versionroot == null)
|
||||
versionroot = "2.7.3"
|
||||
versionroot = "2.7.4"
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = versionroot + '.' + buildnumber
|
||||
|
@ -24,7 +24,6 @@ import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -34,14 +33,11 @@ import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.RepaintManager;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.api.ILogger;
|
||||
import org.jackhuang.hmcl.api.PluginManager;
|
||||
import org.jackhuang.hmcl.api.VersionNumber;
|
||||
import org.jackhuang.hmcl.laf.HelloMinecraftLookAndFeel;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.ui.LogWindow;
|
||||
import org.jackhuang.hmcl.ui.MainFrame;
|
||||
@ -57,6 +53,7 @@ import org.jackhuang.hmcl.util.log.layout.DefaultLayout;
|
||||
import org.jackhuang.hmcl.util.sys.ProcessManager;
|
||||
import org.jackhuang.hmcl.util.ui.MyRepaintManager;
|
||||
import org.jackhuang.hmcl.util.upgrade.IUpgrader;
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -97,7 +94,7 @@ public final class Main implements Runnable {
|
||||
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
||||
}
|
||||
|
||||
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||
//private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||
|
||||
@ -190,10 +187,9 @@ public final class Main implements Runnable {
|
||||
MessageBox.showLocalized("ui.message.open_jdk");
|
||||
|
||||
try {
|
||||
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
||||
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
||||
BeautyEyeLNFHelper.launchBeautyEyeLNF();
|
||||
RepaintManager.setCurrentManager(new MyRepaintManager());
|
||||
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
||||
} catch (Exception ex) {
|
||||
HMCLog.warn("Failed to set look and feel...", ex);
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
<Component class="javax.swing.JTable" name="lstDownloads">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class}, new boolean[]{false, false, false})" type="code"/>
|
||||
<Connection code="SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.release_time"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class, String.class}, new boolean[]{false, false, false, false})" type="code"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
|
||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.Page;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
import org.jackhuang.hmcl.core.download.MinecraftRemoteVersions;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
@ -64,7 +65,7 @@ public class GameDownloadPanel extends Page {
|
||||
}
|
||||
});
|
||||
|
||||
lstDownloads.setModel(SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class}, new boolean[]{false, false, false}));
|
||||
lstDownloads.setModel(SwingUtils.makeDefaultTableModel(new String[]{C.i18n("install.version"), C.i18n("install.release_time"), C.i18n("install.time"), C.i18n("install.type")},new Class[]{String.class, String.class, String.class, String.class}, new boolean[]{false, false, false, false}));
|
||||
lstDownloads.setToolTipText("");
|
||||
lstDownloads.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
jScrollPane2.setViewportView(lstDownloads);
|
||||
@ -110,7 +111,7 @@ public class GameDownloadPanel extends Page {
|
||||
DefaultTableModel model = SwingUtils.clearDefaultTable(lstDownloads);
|
||||
model.addRow(new Object[] { C.i18n("message.loading"), "", "" });
|
||||
MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType())
|
||||
.reg((ver) -> model.addRow(new Object[] { ver.id, ver.time,
|
||||
.reg((ver) -> model.addRow(new Object[] { ver.id, ver.releaseTime, ver.time,
|
||||
StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type }))
|
||||
.regDone(SwingUtils.invokeLater(() -> {
|
||||
lstDownloads.requestFocus();
|
||||
@ -138,8 +139,8 @@ public class GameDownloadPanel extends Page {
|
||||
boolean refreshedDownloads = false;
|
||||
|
||||
@Override
|
||||
public void onSelect() {
|
||||
super.onSelect();
|
||||
public void onSelect(TopTabPage page) {
|
||||
super.onSelect(page);
|
||||
if (!refreshedDownloads) {
|
||||
refreshedDownloads = true;
|
||||
refreshDownloads();
|
||||
|
@ -26,7 +26,7 @@
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tabVersionEdit" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="tabVersionEdit" alignment="1" pref="766" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="btnMakeLaunchScript" min="-2" max="-2" attributes="0"/>
|
||||
@ -42,7 +42,7 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnIncludeMinecraft" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="577" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="677" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -50,7 +50,7 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="pnlTop" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pnlTop" min="-2" pref="70" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tabVersionEdit" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -63,7 +63,7 @@
|
||||
</Group>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace pref="400" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="403" max="32767" attributes="0"/>
|
||||
<Component id="btnIncludeMinecraft" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -119,7 +119,7 @@
|
||||
<Component id="lblDimensionX" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtHeight" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="88" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="182" max="32767" attributes="0"/>
|
||||
<Component id="chkFullscreen" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
@ -194,7 +194,7 @@
|
||||
<Component id="lblDimension" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtWidth" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="39" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="51" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnDownloadAllAssets" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnCleanGame" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
@ -408,7 +408,7 @@
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="txtJavaArgs" pref="325" max="32767" attributes="0"/>
|
||||
<Component id="txtJavaArgs" pref="457" max="32767" attributes="0"/>
|
||||
<Component id="txtMinecraftArgs" max="32767" attributes="0"/>
|
||||
<Component id="txtPermSize" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
@ -421,7 +421,7 @@
|
||||
<Component id="chkNoJVMArgs" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkNoCommon" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="96" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="190" max="32767" attributes="0"/>
|
||||
<Component id="chkDontCheckGame" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
@ -627,7 +627,7 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jScrollPane1" pref="550" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="644" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="btnRemoveMod" max="32767" attributes="0"/>
|
||||
@ -635,7 +635,7 @@
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="lblModInfo" pref="646" max="32767" attributes="0"/>
|
||||
<Component id="lblModInfo" pref="751" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -650,7 +650,7 @@
|
||||
<Component id="btnRemoveMod" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane1" pref="259" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="271" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lblModInfo" min="-2" max="-2" attributes="0"/>
|
||||
@ -723,6 +723,9 @@
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pnlAutoInstall">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new Page()"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="<settings.tabs.installers>">
|
||||
|
@ -322,7 +322,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
btnAddMod = new javax.swing.JButton();
|
||||
btnRemoveMod = new javax.swing.JButton();
|
||||
lblModInfo = new javax.swing.JLabel();
|
||||
pnlAutoInstall = new javax.swing.JPanel();
|
||||
pnlAutoInstall = new Page();
|
||||
tabInstallers = new NewTabPane();
|
||||
pnlTop = new javax.swing.JPanel();
|
||||
pnlSelection = new javax.swing.JPanel();
|
||||
@ -479,7 +479,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addComponent(lblDimensionX)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtHeight, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 88, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 182, Short.MAX_VALUE)
|
||||
.addComponent(chkFullscreen))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlSettingsLayout.createSequentialGroup()
|
||||
.addComponent(txtMaxMemory)
|
||||
@ -539,7 +539,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addComponent(lblDimensionX, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblDimension)
|
||||
.addComponent(txtWidth, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 51, Short.MAX_VALUE)
|
||||
.addGroup(pnlSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnDownloadAllAssets)
|
||||
.addComponent(btnCleanGame))
|
||||
@ -632,7 +632,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addComponent(lblJavaArgs))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(txtJavaArgs, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
|
||||
.addComponent(txtJavaArgs, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE)
|
||||
.addComponent(txtMinecraftArgs)
|
||||
.addComponent(txtPermSize, javax.swing.GroupLayout.Alignment.TRAILING)))
|
||||
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
|
||||
@ -643,7 +643,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addComponent(chkNoJVMArgs)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkNoCommon)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 96, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 190, Short.MAX_VALUE)
|
||||
.addComponent(chkDontCheckGame))
|
||||
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
|
||||
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -728,13 +728,13 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
pnlModManagementContentLayout.setHorizontalGroup(
|
||||
pnlModManagementContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlModManagementContentLayout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 644, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlModManagementContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(btnRemoveMod, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnAddMod, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlModManagementContentLayout.createSequentialGroup()
|
||||
.addComponent(lblModInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 646, Short.MAX_VALUE)
|
||||
.addComponent(lblModInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 751, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
pnlModManagementContentLayout.setVerticalGroup(
|
||||
@ -746,7 +746,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnRemoveMod)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 271, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblModInfo))
|
||||
);
|
||||
@ -950,7 +950,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabVersionEdit, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(tabVersionEdit, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 766, Short.MAX_VALUE)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(btnMakeLaunchScript)
|
||||
@ -963,12 +963,12 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(btnIncludeMinecraft)
|
||||
.addContainerGap(577, Short.MAX_VALUE)))
|
||||
.addContainerGap(677, Short.MAX_VALUE)))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(pnlTop, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(pnlTop, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tabVersionEdit)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@ -979,7 +979,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
|
||||
.addContainerGap())
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap(400, Short.MAX_VALUE)
|
||||
.addContainerGap(403, Short.MAX_VALUE)
|
||||
.addComponent(btnIncludeMinecraft)
|
||||
.addContainerGap()))
|
||||
);
|
||||
|
@ -21,6 +21,7 @@ import org.jackhuang.hmcl.util.ui.Page;
|
||||
import java.util.List;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hmcl.api.ui.TopTabPage;
|
||||
import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.core.install.InstallerType;
|
||||
@ -164,7 +165,8 @@ public class InstallerPanel extends Page {
|
||||
boolean refreshed = false;
|
||||
|
||||
@Override
|
||||
public void onSelect() {
|
||||
public void onSelect(TopTabPage page) {
|
||||
super.onSelect(page);
|
||||
if (!refreshed) {
|
||||
TaskWindow.factory().execute(refreshVersionsTask());
|
||||
refreshed = true;
|
||||
|
@ -37,6 +37,7 @@ import org.jackhuang.hmcl.util.C;
|
||||
import org.jackhuang.hmcl.util.MessageBox;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.DefaultPlugin;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.sys.ProcessMonitor;
|
||||
import org.jackhuang.hmcl.util.net.WebFrame;
|
||||
@ -111,6 +112,7 @@ public class LaunchingUIDaemon {
|
||||
void runGame(Profile profile) {
|
||||
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
|
||||
profile.launcher().genLaunchCode(value -> {
|
||||
DefaultPlugin.INSTANCE.saveAuthenticatorConfig();
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 1;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
@ -118,6 +120,7 @@ public class LaunchingUIDaemon {
|
||||
void makeLaunchScript(Profile profile) {
|
||||
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
|
||||
profile.launcher().genLaunchCode(value -> {
|
||||
DefaultPlugin.INSTANCE.saveAuthenticatorConfig();
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 2;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
@ -154,9 +157,8 @@ public class LaunchingUIDaemon {
|
||||
if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) {
|
||||
HMCLog.log("Launcher will exit now.");
|
||||
System.exit(0);
|
||||
} else {
|
||||
} else
|
||||
HMCLog.log("Launcher will not exit now.");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Consumer<LaunchSucceededEvent> LAUNCH_SCRIPT_FINISHER = event -> {
|
||||
|
@ -40,6 +40,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
@ -49,6 +50,7 @@ import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.Main;
|
||||
import org.jackhuang.hmcl.api.PluginManager;
|
||||
@ -165,7 +167,6 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(null);
|
||||
initBorderColor(Settings.getInstance().getTheme());
|
||||
|
||||
realPanel = new JPanel();
|
||||
realPanel.setLayout(null);
|
||||
@ -255,6 +256,8 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
|
||||
realPanel.setBounds(1, 0, 800, 511);
|
||||
add(realPanel);
|
||||
|
||||
reloadColor(Settings.getInstance().getTheme());
|
||||
}
|
||||
|
||||
private transient final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand());
|
||||
@ -277,11 +280,12 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
|
||||
public void selectTab(String tabName) {
|
||||
int chosen = -1;
|
||||
TopTabPage onCreate = null, onSelect = null;
|
||||
TopTabPage onCreate = null, onSelect = null, lastPage = null;
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (tabName.equalsIgnoreCase(tabHeader.get(i).getActionCommand())) {
|
||||
if (!tabContent.get(i).isCreated()) {
|
||||
onCreate = tabContent.get(i);
|
||||
onCreate.setId(i);
|
||||
tabWrapper[i].add(tabContent.get(i));
|
||||
} else if (tabContent.get(i).isSelected())
|
||||
continue;
|
||||
@ -290,8 +294,10 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
}
|
||||
if (chosen != -1) {
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (i != chosen && tabContent.get(i) != null && tabContent.get(i).isSelected())
|
||||
tabContent.get(i).onLeave();
|
||||
if (i != chosen && tabContent.get(i) != null && tabContent.get(i).isSelected()) {
|
||||
lastPage = tabContent.get(i);
|
||||
lastPage.onLeave();
|
||||
}
|
||||
for (int i = 0; i < tabHeader.size(); i++)
|
||||
if (i == chosen) {
|
||||
for (int j = 0; j < tabHeader.size(); j++)
|
||||
@ -305,7 +311,7 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
if (onCreate != null)
|
||||
onCreate.onCreate();
|
||||
if (onSelect != null)
|
||||
onSelect.onSelect();
|
||||
onSelect.onSelect(lastPage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,13 +388,18 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
|
||||
Color borderColor;
|
||||
Color borderColorDarker;
|
||||
|
||||
private void initBorderColor(Theme t) {
|
||||
borderColor = GraphicsUtils.getWebColor(t.settings.get("Customized.MainFrame.background"));
|
||||
borderColorDarker = GraphicsUtils.getWebColor(t.settings.get("Customized.MainFrame.selected_background"));
|
||||
private void initBorderColor() {
|
||||
borderColor = UIManager.getColor("Customized.MainFrame.background");
|
||||
borderColorDarker = UIManager.getColor("Customized.MainFrame.selected_background");
|
||||
}
|
||||
|
||||
public void reloadColor(Theme t) {
|
||||
initBorderColor(t);
|
||||
for (Map.Entry<String, String> entry : t.settings.entrySet()) {
|
||||
if (entry.getValue().startsWith("#"))
|
||||
UIManager.put(entry.getKey(), GraphicsUtils.getWebColor(entry.getValue()));
|
||||
}
|
||||
|
||||
initBorderColor();
|
||||
if (border != null)
|
||||
border.setColor(borderColor);
|
||||
header.setBackground(borderColor);
|
||||
|
@ -45,7 +45,7 @@ import org.jackhuang.hmcl.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.core.mod.ModpackManager;
|
||||
import org.jackhuang.hmcl.ui.modpack.ModpackWizard;
|
||||
import org.jackhuang.hmcl.laf.ConstomButton;
|
||||
import org.jackhuang.hmcl.laf.button.CustomButton;
|
||||
import org.jackhuang.hmcl.api.func.Consumer;
|
||||
import org.jackhuang.hmcl.util.sys.FileUtils;
|
||||
import org.jackhuang.hmcl.util.task.TaskWindow;
|
||||
@ -54,6 +54,7 @@ import org.jackhuang.hmcl.util.ui.JSystemFileChooser;
|
||||
import org.jackhuang.hmcl.util.ui.SwingUtils;
|
||||
import org.jackhuang.hmcl.util.ui.wizard.api.WizardDisplayer;
|
||||
import org.jackhuang.hmcl.api.auth.IAuthenticator;
|
||||
import org.jackhuang.hmcl.laf.button.CustomButtonUI;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -67,13 +68,11 @@ public class MainPagePanel extends Page {
|
||||
void initGui() {
|
||||
initComponents();
|
||||
|
||||
animationEnabled = false;
|
||||
|
||||
pnlButtons = new javax.swing.JPanel();
|
||||
pnlButtons.setLayout(null);
|
||||
|
||||
int w = 150, h = 50;
|
||||
btnRun = new ConstomButton();
|
||||
btnRun = new CustomButton();
|
||||
btnRun.setBounds(0, 0, w, h);
|
||||
Font font = btnRun.getFont();
|
||||
Font newFont = new Font(font.getName(), font.getStyle(), 15);
|
||||
@ -82,6 +81,7 @@ public class MainPagePanel extends Page {
|
||||
btnRun.setText(C.i18n("ui.button.run"));
|
||||
btnRun.setFont(newFont);
|
||||
btnRun.addActionListener(e -> MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile()));
|
||||
btnRun.setUI(new CustomButtonUI());
|
||||
|
||||
pnlRoot.add(pnlButtons);
|
||||
pnlButtons.setBounds(0, 0, w, h);
|
||||
@ -434,7 +434,7 @@ public class MainPagePanel extends Page {
|
||||
boolean preparingAuth = true;
|
||||
private boolean isLoading = false;
|
||||
private javax.swing.JPanel pnlButtons;
|
||||
private ConstomButton btnRun;
|
||||
private CustomButton btnRun;
|
||||
private static final int DEFAULT_WIDTH = 800, DEFAULT_HEIGHT = 480;
|
||||
//</editor-fold>
|
||||
|
||||
|
@ -40,10 +40,20 @@ public class NewTabPane extends JTabbedPane implements ChangeListener {
|
||||
if (initializing)
|
||||
return;
|
||||
for (int i = 0; i < getComponentCount(); ++i)
|
||||
if (getSelectedIndex() != i && getComponent(i) instanceof TopTabPage)
|
||||
((TopTabPage) getComponent(i)).onLeave();
|
||||
if (getSelectedComponent() instanceof TopTabPage)
|
||||
((TopTabPage) getSelectedComponent()).onSelect();
|
||||
if (getComponent(i) instanceof TopTabPage) {
|
||||
TopTabPage comp = (TopTabPage) getComponent(i);
|
||||
comp.setId(i);
|
||||
if (getSelectedIndex() != i)
|
||||
((TopTabPage) getComponent(i)).onLeave();
|
||||
}
|
||||
if (getSelectedComponent() instanceof TopTabPage) {
|
||||
if (page == null && getComponentCount() > 0 && getComponent(0) instanceof TopTabPage)
|
||||
page = (TopTabPage) getComponent(0);
|
||||
((TopTabPage) getSelectedComponent()).onSelect(page);
|
||||
page = (TopTabPage) getSelectedComponent();
|
||||
}
|
||||
}
|
||||
|
||||
TopTabPage page = null;
|
||||
|
||||
}
|
||||
|
@ -37,8 +37,10 @@ import org.jackhuang.hmcl.laf.LAFTheme;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DefaultPlugin implements IPlugin {
|
||||
public static DefaultPlugin INSTANCE;
|
||||
|
||||
public DefaultPlugin() {
|
||||
INSTANCE = this;
|
||||
for (Theme t : LAFTheme.THEMES)
|
||||
Theme.THEMES.put(t.getId(), t);
|
||||
}
|
||||
@ -52,11 +54,8 @@ public class DefaultPlugin implements IPlugin {
|
||||
auths.add(new YggdrasilAuthenticator(clientToken));
|
||||
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
for (IAuthenticator i : auths)
|
||||
Settings.getInstance().setAuthenticatorConfig(i.id(), i.onSaveSettings());
|
||||
}));
|
||||
} catch(IllegalStateException ignore) { // Shutdown in progress
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::saveAuthenticatorConfig));
|
||||
} catch (IllegalStateException ignore) { // Shutdown in progress
|
||||
}
|
||||
for (IAuthenticator i : auths) {
|
||||
i.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(i.id()));
|
||||
@ -64,6 +63,11 @@ public class DefaultPlugin implements IPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAuthenticatorConfig() {
|
||||
for (IAuthenticator i : auths)
|
||||
Settings.getInstance().setAuthenticatorConfig(i.id(), i.onSaveSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddTab(JFrame frame, AddTabCallback callback) {
|
||||
callback.addTab(new MainPagePanel(), "main", C.i18n("launcher.title.main"));
|
||||
|
@ -29,9 +29,13 @@ public abstract class TopTabPage extends JPanel {
|
||||
|
||||
public abstract boolean isCreated();
|
||||
|
||||
public abstract void onSelect();
|
||||
public abstract void onSelect(TopTabPage lastSelectedPage);
|
||||
|
||||
public abstract boolean isSelected();
|
||||
|
||||
public abstract void onLeave();
|
||||
|
||||
public abstract int getId();
|
||||
|
||||
public abstract void setId(int id);
|
||||
}
|
||||
|
@ -17,15 +17,10 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.sys;
|
||||
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
import org.jackhuang.hmcl.util.code.Charsets;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
|
||||
/**
|
||||
@ -68,56 +63,20 @@ public enum OS {
|
||||
*/
|
||||
public static long getTotalPhysicalMemory() {
|
||||
try {
|
||||
if (os() == LINUX)
|
||||
return memoryInfoForLinux()[0] * 1024;
|
||||
else {
|
||||
OperatingSystemMXBean o = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||
return o.getTotalPhysicalMemorySize();
|
||||
}
|
||||
return ReflectionHelper.get(ManagementFactory.getOperatingSystemMXBean(), "getTotalPhysicalMemorySize");
|
||||
} catch (Throwable t) {
|
||||
HMCLog.warn("Failed to get total physical memory size", t);
|
||||
return -1;
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSuggestedMemorySize() {
|
||||
long total = getTotalPhysicalMemory();
|
||||
if (total == -1)
|
||||
return 1024;
|
||||
int memory = (int) (total / 1024 / 1024) / 4;
|
||||
memory = Math.round((float) memory / 128.0f) * 128;
|
||||
return memory;
|
||||
}
|
||||
|
||||
public static long[] memoryInfoForLinux() throws IOException {
|
||||
File file = new File("/proc/meminfo");
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(FileUtils.openInputStream(file), Charsets.UTF_8))) {
|
||||
long[] result = new long[4];
|
||||
String str;
|
||||
StringTokenizer token;
|
||||
while ((str = br.readLine()) != null) {
|
||||
token = new StringTokenizer(str);
|
||||
if (!token.hasMoreTokens())
|
||||
continue;
|
||||
|
||||
str = token.nextToken();
|
||||
if (!token.hasMoreTokens())
|
||||
continue;
|
||||
|
||||
if (str.equalsIgnoreCase("MemTotal:"))
|
||||
result[0] = Long.parseLong(token.nextToken());
|
||||
else if (str.equalsIgnoreCase("MemFree:"))
|
||||
result[1] = Long.parseLong(token.nextToken());
|
||||
else if (str.equalsIgnoreCase("SwapTotal:"))
|
||||
result[2] = Long.parseLong(token.nextToken());
|
||||
else if (str.equalsIgnoreCase("SwapFree:"))
|
||||
result[3] = Long.parseLong(token.nextToken());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLinuxReleaseVersion() throws IOException {
|
||||
return FileUtils.read(new File("/etc/issue"));
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import org.jackhuang.hmcl.api.IProcess;
|
||||
public class ProcessThread extends Thread {
|
||||
|
||||
IProcess p;
|
||||
|
||||
|
||||
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
|
||||
public final EventHandler<SimpleEvent<IProcess>> stopEvent = new EventHandler<>();
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.util.sys;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class ReflectionHelper {
|
||||
|
||||
private static Unsafe unsafe = null;
|
||||
private static long objectFieldOffset;
|
||||
|
||||
static {
|
||||
try {
|
||||
unsafe = AccessController.doPrivileged(new PrivilegedExceptionAction<Unsafe> () {
|
||||
@Override
|
||||
public Unsafe run() throws Exception {
|
||||
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
theUnsafe.setAccessible(true);
|
||||
return (Unsafe) theUnsafe.get(null);
|
||||
}
|
||||
});
|
||||
Field overrideField = AccessibleObject.class.getDeclaredField("override");
|
||||
objectFieldOffset = unsafe.objectFieldOffset(overrideField);
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAccessible(AccessibleObject obj) {
|
||||
unsafe.putBoolean(obj, objectFieldOffset, true);
|
||||
}
|
||||
|
||||
public static <T> T get(Object obj, String fieldName) {
|
||||
try {
|
||||
Method method = obj.getClass().getDeclaredMethod(fieldName);
|
||||
setAccessible(method);
|
||||
return (T) method.invoke(obj);
|
||||
} catch (Throwable ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,17 @@ import javax.swing.Timer;
|
||||
public class Page extends TopTabPage {
|
||||
|
||||
boolean selected = false;
|
||||
public int id;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected() {
|
||||
@ -39,9 +50,11 @@ public class Page extends TopTabPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelect() {
|
||||
if (!selected)
|
||||
public void onSelect(TopTabPage lastSelectedPage) {
|
||||
if (!selected) {
|
||||
lastPage = (Page) lastSelectedPage;
|
||||
animate();
|
||||
}
|
||||
selected = true;
|
||||
}
|
||||
|
||||
@ -65,13 +78,13 @@ public class Page extends TopTabPage {
|
||||
// -------------------
|
||||
// Animation
|
||||
// -------------------
|
||||
private static final int ANIMATION_LENGTH = 10;
|
||||
private static final int ANIMATION_LENGTH = 5;
|
||||
|
||||
public Page() {
|
||||
timer = new Timer(1, (e) -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Page.this.repaint();
|
||||
offsetX += 0.15;
|
||||
offsetX += 0.14;
|
||||
if (offsetX >= ANIMATION_LENGTH) {
|
||||
timer.stop();
|
||||
Page.this.repaint();
|
||||
@ -80,7 +93,7 @@ public class Page extends TopTabPage {
|
||||
});
|
||||
}
|
||||
|
||||
BufferedImage cache = null;
|
||||
BufferedImage cache = null, lastCache = null;
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
@ -88,33 +101,50 @@ public class Page extends TopTabPage {
|
||||
super.paint(g);
|
||||
return;
|
||||
}
|
||||
double pgs = 1 - Math.sin(Math.PI / 2 / ANIMATION_LENGTH * offsetX);
|
||||
Graphics2D gg = (Graphics2D) g;
|
||||
double pgs = Math.sin(Math.PI / 2 / ANIMATION_LENGTH * offsetX);
|
||||
if (Math.abs(ANIMATION_LENGTH - offsetX) < 0.1) {
|
||||
super.paint(g);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offsetX == 0) {
|
||||
cache = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = cache.createGraphics();
|
||||
if (isOpaque()) {
|
||||
g2d.setColor(getBackground());
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
super.paint(g2d);
|
||||
g2d.dispose();
|
||||
cache = cacheImpl(this);
|
||||
if (lastPage != null)
|
||||
lastCache = cacheImpl(lastPage);
|
||||
}
|
||||
if (pgs > 1)
|
||||
pgs = 1;
|
||||
if (pgs < 0)
|
||||
pgs = 0;
|
||||
Graphics2D gg = (Graphics2D) g;
|
||||
gg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) (1 - pgs)));
|
||||
g.drawImage(cache, (int) (pgs * 50), 0, this);
|
||||
int ori = lastPage != null ? (lastPage.getId() < getId() ? 1 : -1) : 1;
|
||||
if (pgs >= 0.5)
|
||||
animateImpl(gg, cache, (int) (((1 - (pgs - 0.5) * 2)) * totalOffset * ori), (float) ((pgs - 0.5) * 2));
|
||||
else
|
||||
animateImpl(gg, lastCache, (int) (((- pgs * 2)) * totalOffset * ori), (float) (1 - pgs * 2));
|
||||
}
|
||||
|
||||
double offsetX = ANIMATION_LENGTH;
|
||||
BufferedImage cacheImpl(Page page) {
|
||||
BufferedImage image = new BufferedImage(page.getWidth(), page.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
if (isOpaque()) {
|
||||
g2d.setColor(page.getBackground());
|
||||
g2d.fillRect(0, 0, page.getWidth(), page.getHeight());
|
||||
}
|
||||
page.superPaint(g2d);
|
||||
g2d.dispose();
|
||||
return image;
|
||||
}
|
||||
|
||||
void animateImpl(Graphics2D g, BufferedImage image, int left, float alpha) {
|
||||
if (image == null)
|
||||
return;
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||||
g.drawImage(image, left, 0, this);
|
||||
}
|
||||
|
||||
protected void superPaint(Graphics2D g) {
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
double offsetX = ANIMATION_LENGTH, totalOffset = 20;
|
||||
Page lastPage;
|
||||
Timer timer;
|
||||
|
||||
protected boolean animationEnabled = true;
|
||||
|
@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BeautyEyeLNFHelper.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import org.jackhuang.hmcl.laf.widget.border.BEShadowBorder;
|
||||
import org.jackhuang.hmcl.laf.widget.border.BEShadowBorder3;
|
||||
import org.jackhuang.hmcl.laf.widget.border.PlainGrayBorder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BeautyEye Swing外观实现方案 - L&F核心辅助类.<br>
|
||||
* <p>
|
||||
* 项目托管地址:https://github.com/JackJiang2011/beautyeye
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-05
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BeautyEyeLNFHelper {
|
||||
|
||||
/**
|
||||
* 开关量:用于开启/关闭BeautyEye LNF的调试信息输出.
|
||||
* <p>
|
||||
* 默认false,即不开启调试信息输出.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static boolean debug = false;
|
||||
/**
|
||||
* 开关量:用于开启/关闭当窗口(包括JFrame、JDialog)处于非活动 状态(inactivity)时的半透明视觉效果.
|
||||
* <p>
|
||||
* 默认true,即表示默认开启半透明效果.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static boolean translucencyAtFrameInactive = true;
|
||||
|
||||
/**
|
||||
* BeautyEye LNF 的窗口边框样式.
|
||||
* <p>
|
||||
* 默认值:运行在java1.6.0_u10及以上版本时使用
|
||||
* {@link FrameBorderStyle#translucencyAppleLike},
|
||||
* 运行在java1.5版本时使用{@link FrameBorderStyle#generalNoTranslucencyShadow}.
|
||||
*
|
||||
* <p>
|
||||
* <b>注意:</b>如需设置本参数,请确保它在UIManager.setLookAndFeel前被设置,否则将不会起效哦.
|
||||
*
|
||||
* @see FrameBorderStyle
|
||||
*/
|
||||
public static FrameBorderStyle frameBorderStyle = FrameBorderStyle.translucencyAppleLike;
|
||||
|
||||
/**
|
||||
* 颜色全局变量:正常情况下的窗口文本颜色.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过{@code UIManager.put("activeCaptionText",new ColorUIResource(c))}和
|
||||
* {@code UIManager.put("inactiveCaptionText",new ColorUIResource(c))}来实现窗口文本颜色的改变.
|
||||
* <p>
|
||||
* 窗体不活动(inactivite)时的颜色将据此自动计算出来,无需额外设置. 默认是黑色(new Color(0,0,0)).
|
||||
*/
|
||||
public static Color activeCaptionTextColor = new Color(0, 0, 0);//黑色
|
||||
|
||||
/**
|
||||
* 颜色全局变量:多数组件的背景色.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是浅灰色(new Color(250,250,250)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonBackgroundColor = new Color(250, 250, 250);//240,240,240); //248,248,248);//255,255,255);//
|
||||
/**
|
||||
* 颜色全局变量:多数组件的前景色(文本颜色).
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是深灰色(new Color(60,60,60)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonForegroundColor = new Color(60, 60, 60);//102,102,102);
|
||||
/**
|
||||
* 颜色全局变量:某些组件的焦点边框颜色. 当前主要用于按钮等焦点边框的绘制颜色.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是浅灰色(new Color(250,250,250)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonFocusedBorderColor = new Color(162, 162, 162);
|
||||
/**
|
||||
* 颜色全局变量:某些组件被禁用时的文本颜色. 当前主要用于菜单项中.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是浅灰色(new Color(172,168,153)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonDisabledForegroundColor = new Color(172, 168, 153);
|
||||
/**
|
||||
* 颜色全局变量:多数组件中文本被选中时的背景色.当前主要用于各文本组件等.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是深灰色(new Color(2,129,216)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonSelectionBackgroundColor = new Color(2, 129, 216);//78,155,193));//58,135,173));//235,217,147));//new Color(255,237,167));
|
||||
/**
|
||||
* 颜色全局变量:多数组件中文本被选中时的前景色(文本颜色).当前主要用于各文本组件、菜单项等.
|
||||
* <p>
|
||||
* 你可设置本变量,也可直接通过各自的UIManager属性来改变它们.
|
||||
* <p>
|
||||
* 默认是深灰色(new Color(255,255,255)).
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static Color commonSelectionForegroundColor = new Color(255, 255, 255);
|
||||
|
||||
/**
|
||||
* 开关量:用于默认设置或不设置窗口(Frame及其子类)的设置此窗体的最大化边界.
|
||||
* <p>
|
||||
* 此开关量是它是为了解决这样一个问题 :<br>
|
||||
* 当不使用操作系统的窗口装饰(即使用完全自定义的窗口标题、边框)时,在windows上最 大化窗口时将会全屏显示从而覆盖了下方的任务栏(task
|
||||
* bar),这个问题 据说自2002年 就已存在,SUN一直未解决或者根本不认为是bug。目前的解决方案是当本变量是true时则
|
||||
* 默认为每一个窗体设置最大化边界,否则保持系统默认。不过这样设置并非完美方案:一旦 设置了最大边界,则此后无论Task Bar再怎么调
|
||||
* 整大小,比如被hide了,则窗体永远是设 置时的最大边界,不过目前也只能这么折中解决了,因为窗体最大化事件处理并非L&F中实现
|
||||
* ,暂未找到其它更好的方法。
|
||||
* <p>
|
||||
* 默认true,即表示默认开启此设置.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see javax.swing.JFrame#setMaximizedBounds(java.awt.Rectangle)
|
||||
*/
|
||||
public static boolean setMaximizedBoundForFrame = true;
|
||||
|
||||
/**
|
||||
* BeautyEye LNF的外观实现核心方法.
|
||||
* <p>
|
||||
* 本方法可以直接从外部调用,这意味着BeautyEye LNF的外观核心实现无需特定于LookAndFeel的实例.
|
||||
* <p>
|
||||
* 也就是说任意外观都可应用本方法所作的外观实现(并保证跨平台),以使之可灵活应用.
|
||||
*
|
||||
* @see org.jb2011.lnf.beautyeye.titlepane.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.tab.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.button.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.separator.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.scroll.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.table.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.textcoms.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.popup.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.toolbar.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.menu.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.internalframe.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.progress.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.radio$cb_btn.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.combox.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.slider.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.tree.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.split.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.spinner.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.list.__UI__#uiImpl()
|
||||
* @see org.jb2011.lnf.beautyeye.filechooser.__UI__#uiImpl_win()
|
||||
*/
|
||||
protected static void implLNF() {
|
||||
//自定义窗口的L&F实现
|
||||
org.jackhuang.hmcl.laf.titlepane.__UI__.uiImpl();
|
||||
//自定义JTabbedPane的L&F实现
|
||||
org.jackhuang.hmcl.laf.tab.__UI__.uiImpl();
|
||||
//自定义按钮的L&F实现
|
||||
org.jackhuang.hmcl.laf.button.__UI__.uiImpl();
|
||||
//各种杂七杂八的设置
|
||||
org.jackhuang.hmcl.laf.separator.__UI__.uiImpl();
|
||||
//自定义滚动条的L&F实现
|
||||
org.jackhuang.hmcl.laf.scroll.__UI__.uiImpl();
|
||||
//自定义表格头的L&F实现
|
||||
org.jackhuang.hmcl.laf.table.__UI__.uiImpl();
|
||||
//自定义文本组件的L&F实现
|
||||
org.jackhuang.hmcl.laf.textcoms.__UI__.uiImpl();
|
||||
//自定义弹出组件(包括toolTip组件和弹出菜单等)的L&F实现
|
||||
org.jackhuang.hmcl.laf.popup.__UI__.uiImpl();
|
||||
//自定义ToggleButton的L&F实现
|
||||
org.jackhuang.hmcl.laf.toolbar.__UI__.uiImpl();
|
||||
//自定义菜单项的L&F实现
|
||||
org.jackhuang.hmcl.laf.menu.__UI__.uiImpl();
|
||||
//自定义DesktopPane及内部窗体的L&F实现
|
||||
org.jackhuang.hmcl.laf.internalframe.__UI__.uiImpl();
|
||||
//自定义进度条的L&F实现
|
||||
org.jackhuang.hmcl.laf.progress.__UI__.uiImpl();
|
||||
//自定义单选按钮的L&F实现
|
||||
org.jackhuang.hmcl.laf.radio$cb_btn.__UI__.uiImpl();
|
||||
//自定义下拉框的L&F实现
|
||||
org.jackhuang.hmcl.laf.combox.__UI__.uiImpl();
|
||||
//自定义JSlider的L&F实现
|
||||
org.jackhuang.hmcl.laf.slider.__UI__.uiImpl();
|
||||
//自定义Jtree的L&F实现
|
||||
org.jackhuang.hmcl.laf.tree.__UI__.uiImpl();
|
||||
//自定义JSplitPane的L&F实现
|
||||
org.jackhuang.hmcl.laf.split.__UI__.uiImpl();
|
||||
//自定义JSpinner的L&F实现
|
||||
org.jackhuang.hmcl.laf.spinner.__UI__.uiImpl();
|
||||
//自定义JList的L&F实现
|
||||
org.jackhuang.hmcl.laf.list.__UI__.uiImpl();
|
||||
//自定义JFileChooser的L&F实现
|
||||
org.jackhuang.hmcl.laf.filechooser.__UI__.uiImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the beauty eye lnf platform.
|
||||
*
|
||||
* @return {@code new BeautyEyeLookAndFeel()}
|
||||
*/
|
||||
public static LookAndFeel getBeautyEyeLNFPlatform() {
|
||||
return new BeautyEyeLookAndFeel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 实施BeautyEye外观.<b>开发者使用BeautyEye L&F时应首选本方法.</b>
|
||||
* <p>
|
||||
* 本方法会据操作系统类型不同,来决定主类是使用BeautyEyeLookAndFeelWin还是BeautyEyeLookAndFeelWin.
|
||||
* 使用BeautyEye外观时推荐使用本方法来设置外观.之所以有平台不同主类不同的区分,是为了
|
||||
* 在Windows上平台上能更好的使用与操作系统相同的字体等设置.
|
||||
*
|
||||
* @throws Exception {@link UIManager#setLookAndFeel(String)}过程中出现的任何异常
|
||||
* @see #getBeautyEyeLNFStrWindowsPlatform()
|
||||
* @see #getBeautyEyeLNFPlatform()
|
||||
* @see org.jb2011.lnf.beautyeye.utils.Platform
|
||||
*/
|
||||
public static void launchBeautyEyeLNF() throws Exception {
|
||||
System.setProperty("sun.java2d.noddraw", "true");
|
||||
UIManager.setLookAndFeel(getBeautyEyeLNFPlatform());
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>开发者无需关注本方法.</b>
|
||||
* <p>
|
||||
* true表示当前正在使用的窗口边框是不透明的,否则表示透明. 本方法目前作为BERootPaneUI中设置窗口是否透明的开关使用.
|
||||
* <p>
|
||||
* #### 官方API中存的Bug: ####<br>
|
||||
* 在jdk1.6.0_u33下+win7平台下(其它版本是否也有这情况尚未完全验证),JFrame窗口
|
||||
* 被设置成透明后,该窗口内所有文本都会被反走样(不管你有没有要求反走样),真悲具。
|
||||
* 这应该是官方AWTUtilities.setWindowOpaque(..)bug导致的,1.7.0_u6同样存在该问题,
|
||||
* 使用BeautyEye时,遇到这样的问题只能自行使用本方法中指定的不透明边框才行(这样
|
||||
* BERootPaneUI类的设置窗口透明的代码就不用执行,也就不用触发该bug了),但JDialog 不受此bug影响,诡异!
|
||||
*
|
||||
* @return true, if successful
|
||||
* @since 3.2
|
||||
*/
|
||||
public static boolean isFrameBorderOpaque() {
|
||||
return frameBorderStyle == FrameBorderStyle.osLookAndFeelDecorated
|
||||
|| frameBorderStyle == FrameBorderStyle.generalNoTranslucencyShadow;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>开发者无需关注本方法.</b>
|
||||
* <p>
|
||||
* 根据设置的frameBorderStyle来返回正确的窗口边框.
|
||||
*
|
||||
* @return
|
||||
* 当frameBorderStyle=={@link FrameBorderStyle#defaultLookAndFeelDecorated}
|
||||
* 时返回无意义的BorderFactory.createEmptyBorder(),否则返回指定边框对象
|
||||
*/
|
||||
public static Border getFrameBorder() {
|
||||
switch (frameBorderStyle) {
|
||||
case osLookAndFeelDecorated:
|
||||
return BorderFactory.createEmptyBorder();
|
||||
case translucencyAppleLike:
|
||||
return new BEShadowBorder3();
|
||||
case translucencySmallShadow:
|
||||
return new BEShadowBorder();
|
||||
case generalNoTranslucencyShadow:
|
||||
default:
|
||||
return new PlainGrayBorder();
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * <b>开发者无需关注本方法.</b>
|
||||
// * <p>
|
||||
// * 根据设置的frameBorderStyle来返回正确的窗口边框边角的拖动区大小.
|
||||
// * <p>
|
||||
// * <b>重要说明:</b>本方法中的边框类型及其对应的边框类必须与方法 {@link #__getFrameBorder()}
|
||||
// * 完全一致!
|
||||
// *
|
||||
// * @return 当frameBorderStyle=={@link FrameBorderStyle#defaultLookAndFeelDecorated}
|
||||
// * 时返回null,否则返回指定边框对象
|
||||
// */
|
||||
// public static int __getFrameBorder_CORNER_DRAG_WIDTH()
|
||||
// {
|
||||
// switch(frameBorderStyle)
|
||||
// {
|
||||
// case osLookAndFeelDecorated:
|
||||
// return 16;
|
||||
// case translucencyAppleLike:
|
||||
// return BEShadowBorder3.CORNER_DRAG_WIDTH();
|
||||
// case translucencySmallShadow:
|
||||
// return new BEShadowBorder().CORNER_DRAG_WIDTH();
|
||||
// case generalNoTranslucencyShadow:
|
||||
// default:
|
||||
// return new PlainGrayBorder().CORNER_DRAG_WIDTH();
|
||||
// }
|
||||
// }
|
||||
// /**
|
||||
// * <b>开发者无需关注本方法.</b>
|
||||
// * <p>
|
||||
// * 根据设置的frameBorderStyle来返回正确的窗口边框拖动区大小.
|
||||
// * <p>
|
||||
// * <b>重要说明:</b>本方法中的边框类型及其对应的边框类必须与方法 {@link #__getFrameBorder()}
|
||||
// * 完全一致!
|
||||
// *
|
||||
// * @return 当frameBorderStyle=={@link FrameBorderStyle#defaultLookAndFeelDecorated}
|
||||
// * 时返回null,否则返回指定边框对象
|
||||
// */
|
||||
// public static int __getFrameBorder_BORDER_DRAG_THICKNESS()
|
||||
// {
|
||||
// switch(frameBorderStyle)
|
||||
// {
|
||||
// case osLookAndFeelDecorated:
|
||||
// return 5;
|
||||
// case translucencyAppleLike:
|
||||
// return BEShadowBorder3.BORDER_DRAG_THICKNESS();
|
||||
// case translucencySmallShadow:
|
||||
// return new BEShadowBorder().BORDER_DRAG_THICKNESS();
|
||||
// case generalNoTranslucencyShadow:
|
||||
// default:
|
||||
// return new PlainGrayBorder().BORDER_DRAG_THICKNESS();
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* BeautyEye LNF 的窗口边框样式.
|
||||
*/
|
||||
public enum FrameBorderStyle {
|
||||
|
||||
/**
|
||||
* 使用本地系统的窗口装饰样式(本样式将能带来最佳性能,使用操作系统默认窗口样式).
|
||||
*/
|
||||
osLookAndFeelDecorated,
|
||||
/**
|
||||
* 使用类似于MacOSX的强烈立体感半透明阴影边框(本样式性能尚可,视觉效果最佳).
|
||||
*/
|
||||
translucencyAppleLike,
|
||||
/**
|
||||
* 使用不太强烈立体感半透明阴影边框(本样式性能尚可,视觉效果较soft).
|
||||
*/
|
||||
translucencySmallShadow,
|
||||
/**
|
||||
* 使用不透明的普通边框(这是本LNF在Java1.5版默认使用的样式,因为java1.5不支持窗口透明)
|
||||
*/
|
||||
generalNoTranslucencyShadow
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>开发者暂时无需关注此接口.</b>
|
||||
* <p>
|
||||
* 实现了此接口的UI类意味着用户可以通过自行设置诸如border等,来 取消默认的NainePatch图实现的边框填充、背景填充等,具体设置哪
|
||||
* 些东西可以取消默认的NinePatch图填充的方式详见各自的类注释。
|
||||
*/
|
||||
public interface __UseParentPaintSurported {
|
||||
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,进度条和背景都是使用N9图,比如没法通过设置JProgressBar的背景色和前景
|
||||
* 色来控制进度条的颜色,本方法的目的就是当用户设置了进度条的Background或Foreground 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法
|
||||
* 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以 通过JProgressBar.setUI(new
|
||||
* MetalProgressBar())方式来自定义进度的UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
boolean isUseParentPaint();
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BeautyEyeLookAndFeel.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Enumeration;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BeautyEye Swing外观实现方案 - 跨平台通用外观实现主类.<br>
|
||||
* <p>
|
||||
* 本主题主类仅供跨平台时使用,它可用于Java支持的所有操作系统.
|
||||
*
|
||||
* 如果要继承BasicLookAndFeel实现跨平台lnf 则还需要做更多的工作,目前
|
||||
* 跨平台时干脆继承MetalLookAndFeel以便站在巨人的肩膀上,节省一些工作量
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BeautyEyeLookAndFeel extends MetalLookAndFeel {
|
||||
private static void initGlobalFont(Font font) {
|
||||
FontUIResource fontRes = new FontUIResource(font);
|
||||
for (Enumeration<Object> keys = UIManager.getDefaults().keys();
|
||||
keys.hasMoreElements(); ) {
|
||||
Object key = keys.nextElement();
|
||||
Object value = UIManager.get(key);
|
||||
if (value instanceof FontUIResource) {
|
||||
UIManager.put(key, fontRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BeautyEyeLookAndFeel() {
|
||||
super();
|
||||
|
||||
// //本属性仅对windows平台有效?! -> Jack Jiang最终证实没效果!!!!!!!!!!!
|
||||
// UIManager.put("Application.useSystemFontSettings", Boolean.TRUE);
|
||||
//取消Metal LNF中默认的粗体字
|
||||
UIManager.put("swing.boldMetal", Boolean.FALSE);
|
||||
//此项如是true,则将会为TabbedPane的内容面板填充天蓝色背景
|
||||
UIManager.put("TabbedPane.contentOpaque", Boolean.FALSE);
|
||||
//此项如是true,则将会为TabbedPane的标签填充天蓝色背景
|
||||
UIManager.put("TabbedPane.tabsOpaque", Boolean.FALSE);
|
||||
initGlobalFont(new Font("微软雅黑", Font.PLAIN, 12));
|
||||
BeautyEyeLNFHelper.implLNF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "BeautyEye";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "BeautyEye";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "BeautyEye L&F developed by Jack Jiang(jb2011@163.com).";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supports window decorations.
|
||||
*
|
||||
* @return the supports window decorations {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean getSupportsWindowDecorations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativeLookAndFeel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLookAndFeel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initComponentDefaults(UIDefaults table) {
|
||||
super.initComponentDefaults(table);
|
||||
initOtherResourceBundle(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the defaults table with the name of the other ResourceBundle
|
||||
* used for getting localized defaults.
|
||||
*/
|
||||
protected void initOtherResourceBundle(UIDefaults table) {
|
||||
table.addResourceBundle("org.jb2011.lnf.beautyeye.resources.beautyeye");
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.synth.SynthLookAndFeel;
|
||||
import org.jackhuang.hmcl.api.HMCLog;
|
||||
import org.jackhuang.hmcl.util.sys.IOUtils;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HelloMinecraftLookAndFeel extends SynthLookAndFeel {
|
||||
|
||||
public static final Map<String, String> DEFAULT_SETTINGS = LAFTheme.BLUE.settings;
|
||||
|
||||
/**
|
||||
* Creates a new instance of NimbusLookAndFeel
|
||||
*
|
||||
* @throws java.text.ParseException error parsing the xml, it must not
|
||||
* happen.
|
||||
*/
|
||||
public HelloMinecraftLookAndFeel() throws ParseException {
|
||||
this(DEFAULT_SETTINGS);
|
||||
}
|
||||
|
||||
public HelloMinecraftLookAndFeel(Map<String, String> settings) throws ParseException {
|
||||
try {
|
||||
try (InputStream is = HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hmcl/laf/synth.xml")) {
|
||||
String s = IOUtils.toString(is, "UTF-8");
|
||||
for (Map.Entry<String, String> ss : settings.entrySet())
|
||||
s = s.replace("${" + ss.getKey() + "}", ss.getValue());
|
||||
load(new ByteArrayInputStream(s.getBytes("UTF-8")), HelloMinecraftLookAndFeel.class);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
HMCLog.err("This fucking exception should not happen. Retry backup solution.", ex);
|
||||
try {
|
||||
try (InputStream is = HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hmcl/laf/synth_backup.xml")) {
|
||||
load(is, HelloMinecraftLookAndFeel.class);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
HMCLog.err("User fault", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIDefaults uiDefaults;
|
||||
|
||||
@Override
|
||||
public UIDefaults getDefaults() {
|
||||
if (uiDefaults != null)
|
||||
return uiDefaults;
|
||||
uiDefaults = super.getDefaults();
|
||||
//ui.put("Table.selectionForeground", new ColorUIResource(Color.red));
|
||||
//ui.put("Table.focusCellForeground", new ColorUIResource(Color.red));
|
||||
//ui.put("TabbedPane.isTabRollover", false);
|
||||
//ui.put("ComboBox.selectionBackground", new ColorUIResource(Color.red));
|
||||
//ui.put("List.background", new ColorUIResource(Color.red));
|
||||
//uiDefaults.put("TabbedPane.selectedLabelShift", 0);
|
||||
uiDefaults.put("Table.selectionBackground", Color.red);
|
||||
return uiDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a short string that identifies this look and feel.
|
||||
*
|
||||
* @return a short string identifying this look and feel.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "HelloMinecraftLookAndFeel";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string that identifies this look and feel.
|
||||
*
|
||||
* @return a short string identifying this look and feel.
|
||||
*/
|
||||
@Override
|
||||
public String getID() {
|
||||
return "HelloMinecraftLookAndFeel";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual description of this look and feel.
|
||||
*
|
||||
* @return textual description of this look and feel.
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "HelloMinecraftLookAndFeel";
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an image using ImageIO from resource in
|
||||
* org.jdesktop.swingx.plaf.nimbus.images. Catches and prints all Exceptions
|
||||
* so that it can safely be used in a static context.
|
||||
*
|
||||
* @param imgName The name of the image to load, eg. "border.png"
|
||||
*
|
||||
* @return The loaded image
|
||||
*/
|
||||
public static BufferedImage loadImage(String imgName) {
|
||||
try {
|
||||
return ImageIO.read(GraphicsUtils.class.getClassLoader().getResource("org/jackhuang/hmcl/laf/images/" + imgName));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error loading image \"org/jackhuang/hmcl/laf/images/" + imgName + "\"");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
180
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/Icon9Factory.java
Normal file
180
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/Icon9Factory.java
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class Icon9Factory extends RawCache<NinePatch> {
|
||||
|
||||
/**
|
||||
* 相对路径根(默认是相对于本类的相对物理路径).
|
||||
*/
|
||||
public final static String IMGS_ROOT = "imgs/np";
|
||||
|
||||
@Override
|
||||
protected NinePatch getResource(String relativePath, Class baseClass) {
|
||||
return NinePatchHelper.createNinePatch(baseClass.getResource(relativePath), false);
|
||||
}
|
||||
|
||||
public Icon9Factory(String namespace) {
|
||||
ns = namespace;
|
||||
init();
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
/**
|
||||
* Gets the raw.
|
||||
*
|
||||
* @param relativePath the relative path
|
||||
* @return the raw
|
||||
*/
|
||||
public NinePatch getRaw(String relativePath) {
|
||||
return getRaw(relativePath, this.getClass());
|
||||
}
|
||||
|
||||
HashMap<String, NinePatch> icons = new HashMap<>();
|
||||
|
||||
protected void put(String namespace, String key, String filename) {
|
||||
if (!ns.equals(namespace))
|
||||
return;
|
||||
icons.put(namespace + ":" + key, getRaw(IMGS_ROOT + "/" + filename + ".9.png"));
|
||||
}
|
||||
|
||||
public NinePatch get(String key) {
|
||||
return icons.get(ns + ":" + key);
|
||||
}
|
||||
|
||||
public NinePatch get(String key, String state) {
|
||||
return Icon9Factory.this.get(concat(key, state));
|
||||
}
|
||||
|
||||
public NinePatch getWithEnabled(String key, boolean enabled) {
|
||||
return get(key, enabled ? "" : "disabled");
|
||||
}
|
||||
|
||||
public NinePatch getWithHorizontal(String key, boolean isHorizontal) {
|
||||
return get(key, isHorizontal ? "" : "vertical");
|
||||
}
|
||||
|
||||
public NinePatch getWithButtonState(String key, boolean enabled, boolean pressed) {
|
||||
return get(key, (enabled ? (pressed ? "pressed" : "normal") : "disabled"));
|
||||
}
|
||||
|
||||
public NinePatch getWithScrollState(String key, boolean pressed, boolean over) {
|
||||
return get(key, (pressed ? "pressed" : (over ? "rollover" : "")));
|
||||
}
|
||||
|
||||
public NinePatch getWithComboState(String key, boolean enabled, boolean pressed, boolean over) {
|
||||
return get(key, (enabled ? (pressed ? "pressed" : (over ? "rollover" : "normal")) : "disabled"));
|
||||
}
|
||||
|
||||
private String concat(String a, String b) {
|
||||
if (a.isEmpty() && b.isEmpty())
|
||||
return "";
|
||||
else if (a.isEmpty())
|
||||
return b;
|
||||
else if (b.isEmpty())
|
||||
return a;
|
||||
else
|
||||
return a + "_" + b;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
put("slider_track", "", "slider_track2");
|
||||
put("slider_track", "vertical", "slider_track2_v");
|
||||
put("slider_track", "disabled", "slider_track2_dark");
|
||||
put("slider_track", "vertical_disabled", "slider_track2_v_dark");
|
||||
put("slider_track", "foreground", "slider_track2_forgroud");
|
||||
put("slider_track", "foreground_disabled", "slider_track2_forgroud_disable");
|
||||
put("slider_track", "vertical_foreground", "slider_track2_forgroud_v");
|
||||
put("slider_track", "vertical_foreground_disabled", "slider_track2_forgroud_v_disable");
|
||||
|
||||
put("button_arrow", "normal", "button_arrow");
|
||||
put("button_arrow", "pressed", "button_arrow_pressed");
|
||||
put("button_arrow", "rollover", "button_arrow_rollover");
|
||||
put("button_arrow", "disabled", "button_arrow_disable");
|
||||
|
||||
put("progress_bar", "bg", "progress_bar_bg");
|
||||
put("progress_bar", "bg_vertical", "progress_bar_bg_v");
|
||||
put("progress_bar", "green", "progress_bar_green");
|
||||
put("progress_bar", "blue_vertical", "progress_bar_grean_v");
|
||||
|
||||
put("split_touch", "bg1", "split_touch_bg1");
|
||||
|
||||
put("list", "selected_icon_bg", "list_cell_selected_bg2");
|
||||
|
||||
put("spinner", "", "spinner1_bg");
|
||||
put("spinner", "button_up", "spinner1_btn_up_bg");
|
||||
put("spinner", "button_down", "spinner1_btn_down_bg");
|
||||
put("spinner", "button_up_pressed", "spinner1_btn_up_pressed_bg");
|
||||
put("spinner", "button_down_pressed", "spinner1_btn_down_pressed_bg");
|
||||
put("spinner", "disabled", "spinner1_disable_bg");
|
||||
|
||||
put("button", "normal", "btn_special_default");
|
||||
put("button", "disabled", "btn_special_disabled");
|
||||
put("button", "pressed", "btn_general_pressed");
|
||||
put("button", "rollover", "btn_general_rover");
|
||||
|
||||
put("toggle_button", "selected", "toggle_button_selected");
|
||||
put("toggle_button", "rollover", "toggle_button_rover");
|
||||
|
||||
put("scroll_bar", "vertical", "scroll_bar_v");
|
||||
put("scroll_bar", "vertical_rollover", "scroll_bar_rover_v");
|
||||
put("scroll_bar", "vertical_pressed", "scroll_bar_pressed_v");
|
||||
put("scroll_bar", "horizontal", "scroll_bar_h");
|
||||
put("scroll_bar", "horizontal_rollover", "scroll_bar_rover_h");
|
||||
put("scroll_bar", "horizontal_pressed", "scroll_bar_rover_h");
|
||||
put("scroll_bar", "arrow_bottom", "arrow_toBottom");
|
||||
put("scroll_bar", "arrow_top", "arrow_toTop");
|
||||
put("scroll_bar", "arrow_left", "arrow_toLeft");
|
||||
put("scroll_bar", "arrow_right", "arrow_toRight");
|
||||
put("scroll_bar", "arrow_bottom_rollover", "arrow_toBottom_rover");
|
||||
put("scroll_bar", "arrow_top_rollover", "arrow_toTop_rover");
|
||||
put("scroll_bar", "arrow_left_rollover", "arrow_toLeft_rover");
|
||||
put("scroll_bar", "arrow_right_rollover", "arrow_toRight_rover");
|
||||
put("scroll_bar", "scroll_pane_border", "scroll_pane_bg1");
|
||||
|
||||
put("popup", "popup", "shadow_bg_popup");
|
||||
put("popup", "tooltip", "shadow_bg_tooltip2");
|
||||
|
||||
put("table", "scroll_border", "table_scrollborder1");
|
||||
put("table", "header_cell", "table_header_bg1");
|
||||
put("table", "header_cell_separator", "table_header_separator1");
|
||||
|
||||
put("text", "normal", "bg_login_text_normal");
|
||||
put("text", "pressed", "bg_login_text_pressed");
|
||||
put("text", "disabled", "bg_login_text_disable");
|
||||
put("text", "white", "null_white_bg");
|
||||
|
||||
put("toolbar", "north", "toolbar_bg1");
|
||||
put("toolbar", "south", "toolbar_bg1_SOUTH");
|
||||
put("toolbar", "west", "toolbar_bg1_WEST");
|
||||
put("toolbar", "east", "toolbar_bg1_EAST");
|
||||
|
||||
put("menu", "selected", "menu_bg");
|
||||
|
||||
put("widget", "panel", "query_item_bg_2");
|
||||
put("widget", "hint_light_blue", "hint_bg_lightblue");
|
||||
put("widget", "hint_light_gray", "hint_bg_lightblue_gray");
|
||||
put("widget", "tips", "tips_bg");
|
||||
put("widget", "orange_balloon", "orange_baloon1");
|
||||
put("widget", "border_shadow1", "shadow1");
|
||||
put("widget", "border_shadow2", "shadow2");
|
||||
put("widget", "border_plain_gray", "plain_gray1");
|
||||
put("widget", "border_shadow3", "frame_shadow_border4");
|
||||
|
||||
put("combo", "normal", "combo_normal");
|
||||
put("combo", "disabled", "combo_disabled");
|
||||
put("combo", "rollover", "combo_over");
|
||||
put("combo", "pressed", "combo_pressed");
|
||||
}
|
||||
}
|
150
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/IconFactory.java
Normal file
150
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/IconFactory.java
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class IconFactory extends RawCache<ImageIcon> {
|
||||
|
||||
/**
|
||||
* 相对路径根(默认是相对于本类的相对物理路径).
|
||||
*/
|
||||
public final static String IMGS_ROOT = "imgs";
|
||||
|
||||
public IconFactory(String namespace) {
|
||||
ns = namespace;
|
||||
init();
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
@Override
|
||||
protected ImageIcon getResource(String relativePath, Class baseClass) {
|
||||
return new ImageIcon(baseClass.getResource(relativePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image.
|
||||
*
|
||||
* @param relativePath the relative path
|
||||
* @return the image
|
||||
*/
|
||||
protected ImageIcon getImage(String relativePath) {
|
||||
return getRaw(relativePath, IconFactory.class);
|
||||
}
|
||||
|
||||
HashMap<String, ImageIcon> icons = new HashMap<>();
|
||||
|
||||
protected void put(String namespace, String key, String filename) {
|
||||
if (!ns.equals(namespace))
|
||||
return;
|
||||
icons.put(namespace + ":" + key, getImage(IMGS_ROOT + "/" + filename + ".png"));
|
||||
}
|
||||
|
||||
public ImageIcon get(String... states) {
|
||||
String s = "";
|
||||
for (String k : states)
|
||||
s = concat(s, k);
|
||||
return icons.get(ns + ":" + s);
|
||||
}
|
||||
|
||||
public ImageIcon getWithButtonState(String key, boolean enabled, boolean pressed) {
|
||||
return get(key, (enabled ? (pressed ? "pressed" : "normal") : "disabled"));
|
||||
}
|
||||
|
||||
private String concat(String a, String b) {
|
||||
if (a.isEmpty() && b.isEmpty())
|
||||
return "";
|
||||
else if (a.isEmpty())
|
||||
return b;
|
||||
else if (b.isEmpty())
|
||||
return a;
|
||||
else
|
||||
return a + "_" + b;
|
||||
}
|
||||
|
||||
void init() {
|
||||
put("menu", "radio_check", "RadioButtonMenuItemCheckIcon2");
|
||||
put("menu", "radio_normal", "RadioButtonMenuItemCheckIcon_none");
|
||||
put("menu", "check_selected", "checkbox_menuitem_selected_normal");
|
||||
put("menu", "check_none", "checkbox_menuitem_none");
|
||||
|
||||
put("internal_frame", "close", "frame_close_over");
|
||||
put("internal_frame", "min", "frame_windowize_over");
|
||||
put("internal_frame", "max", "frame_maximize_over");
|
||||
put("internal_frame", "iconify", "frame_minimize_over");
|
||||
put("internal_frame", "icon", "ifi1");
|
||||
|
||||
put("radio", "disabled", "radio_btn_disabled_selected");
|
||||
put("radio", "normal", "radio_btn_selected");
|
||||
put("radio", "pressed", "radio_btn_selected_pressed");
|
||||
put("radio", "over", "radio_btn_selected_over");
|
||||
put("radio", "unchecked_disabled", "radio_btn_disabled_normal");
|
||||
put("radio", "unchecked_normal", "radio_btn");
|
||||
put("radio", "unchecked_pressed", "radio_btn_pressed");
|
||||
put("radio", "unchecked_over", "radio_btn_over");
|
||||
|
||||
put("check", "disabled", "checkbox_on_disabled");
|
||||
put("check", "normal", "checkbox_on");
|
||||
put("check", "pressed", "checkbox_on_pressed");
|
||||
put("check", "over", "checkbox_on_over");
|
||||
put("check", "unchecked_disabled", "checkbox_off_disabled");
|
||||
put("check", "unchecked_normal", "checkbox_off");
|
||||
put("check", "unchecked_pressed", "checkbox_off_pressed");
|
||||
put("check", "unchecked_over", "checkbox_off_over");
|
||||
|
||||
put("menu_radio", "checked", "RadioButtonMenuItemCheckIcon2");
|
||||
put("menu_radio", "normal", "RadioButtonMenuItemCheckIcon_none");
|
||||
put("menu_check", "checked", "checkbox_menuitem_selected_normal");
|
||||
put("menu_check", "normal", "checkbox_menuitem_none");
|
||||
|
||||
put("table", "descending_sort", "desc2");
|
||||
put("table", "ascending_sort", "asc2");
|
||||
|
||||
put("tree", "open", "treeDefaultOpen1");
|
||||
put("tree", "closed", "treeDefaultClosed1");
|
||||
put("tree", "leaf", "leaf1");
|
||||
put("tree", "expanded", "a");
|
||||
put("tree", "collapsed", "b");
|
||||
|
||||
put("option_pane", "warn", "warn");
|
||||
put("option_pane", "error", "error");
|
||||
put("option_pane", "info", "info");
|
||||
put("option_pane", "question", "question");
|
||||
|
||||
put("slider", "", "slider_tick1");
|
||||
put("slider", "disabled", "slider_tick1_dark");
|
||||
put("slider", "vertical", "slider_tick1_v");
|
||||
put("slider", "vertical_disabled", "slider_tick1_v_dark");
|
||||
put("slider", "notriangle", "slider_tick1_notrangle");
|
||||
put("slider", "notriangle_disabled", "slider_tick1_notrangle_dark");
|
||||
put("slider", "notriangle_vertical", "slider_tick1_notrangle_v");
|
||||
put("slider", "notriangle_vertical_disabled", "slider_tick1_notrangle_v_dark");
|
||||
|
||||
put("frame", "close", "frame_close_normal");
|
||||
put("frame", "close_over", "frame_close_rover");
|
||||
put("frame", "close_pressed", "frame_close_pressed");
|
||||
put("frame", "min", "frame_maxwin");
|
||||
put("frame", "min_over", "frame_maxwin_rover");
|
||||
put("frame", "min_pressed", "frame_maxwin_pressed");
|
||||
put("frame", "max", "frame_max_normal");
|
||||
put("frame", "max_over", "frame_max_rover");
|
||||
put("frame", "max_pressed", "frame_max_pressed");
|
||||
put("frame", "iconify", "frame_min_normal");
|
||||
put("frame", "iconify_over", "frame_min_rover");
|
||||
put("frame", "iconify_pressed", "frame_min_pressed");
|
||||
put("frame", "icon", "default_frame_icon");
|
||||
put("frame", "setup", "frame_setup_normal");
|
||||
put("frame", "title_active", "head_bg");
|
||||
put("frame", "title_inactive", "head_inactive");
|
||||
}
|
||||
|
||||
}
|
@ -31,6 +31,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#106CA3");
|
||||
put("Customized.ComboBox.selected_background", "#A0D8F0");
|
||||
put("Customized.MainFrame.background", "#106CA3");
|
||||
put("TabbedPane.selectedForeground", "#106CA3");
|
||||
put("TextField.focused", "#106CA3");
|
||||
put("MenuItem.selectionBackground", "#106CA3");
|
||||
put("Customized.MainFrame.selected_background", "#0C5E91");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
@ -40,6 +43,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#1ABC9C");
|
||||
put("Customized.ComboBox.selected_background", "#1ABC9C");
|
||||
put("Customized.MainFrame.background", "#1ABC9C");
|
||||
put("TabbedPane.selectedForeground", "#1ABC9C");
|
||||
put("TextField.focused", "#1ABC9C");
|
||||
put("MenuItem.selectionBackground", "#1ABC9C");
|
||||
put("Customized.MainFrame.selected_background", "#16A085");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
@ -49,6 +55,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#9B59B6");
|
||||
put("Customized.ComboBox.selected_background", "#9B59B6");
|
||||
put("Customized.MainFrame.background", "#9B59B6");
|
||||
put("TabbedPane.selectedForeground", "#9B59B6");
|
||||
put("TextField.focused", "#9B59B6");
|
||||
put("MenuItem.selectionBackground", "#9B59B6");
|
||||
put("Customized.MainFrame.selected_background", "#8E44AD");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
@ -58,6 +67,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#34495E");
|
||||
put("Customized.ComboBox.selected_background", "#34495E");
|
||||
put("Customized.MainFrame.background", "#34495E");
|
||||
put("TabbedPane.selectedForeground", "#34495E");
|
||||
put("TextField.focused", "#34495E");
|
||||
put("MenuItem.selectionBackground", "#34495E");
|
||||
put("Customized.MainFrame.selected_background", "#2C3E50");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
@ -67,6 +79,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#E67E22");
|
||||
put("Customized.ComboBox.selected_background", "#F39C12");
|
||||
put("Customized.MainFrame.background", "#E67E22");
|
||||
put("TabbedPane.selectedForeground", "#E67E22");
|
||||
put("TextField.focused", "#E67E22");
|
||||
put("MenuItem.selectionBackground", "#E67E22");
|
||||
put("Customized.MainFrame.selected_background", "#D35400");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
@ -76,6 +91,9 @@ public final class LAFTheme {
|
||||
put("Customized.TabbedPaneTab.selected_foreground", "#E74C3C");
|
||||
put("Customized.ComboBox.selected_background", "#E74C3C");
|
||||
put("Customized.MainFrame.background", "#E74C3C");
|
||||
put("TabbedPane.selectedForeground", "#E74C3C");
|
||||
put("TextField.focused", "#E74C3C");
|
||||
put("MenuItem.selectionBackground", "#E74C3C");
|
||||
put("Customized.MainFrame.selected_background", "#C0392B");
|
||||
put("Customized.MainFrame.background_image", "background.jpg");
|
||||
}
|
||||
|
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* MySwingUtilities2.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* 本类中的方法一一对应于SUN未公开的类SwingUtilities2中的方法.
|
||||
*
|
||||
* 部分代码摘自JDK 1.5.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MySwingUtilities2 {
|
||||
|
||||
/**
|
||||
* Returns the FontMetrics for the current Font of the passed in Graphics.
|
||||
* This method is used when a Graphics is available, typically when
|
||||
* painting. If a Graphics is not available the JComponent method of the
|
||||
* same name should be used.
|
||||
* <p>
|
||||
* Callers should pass in a non-null JComponent, the exception to this is if
|
||||
* a JComponent is not readily available at the time of painting.
|
||||
* <p>
|
||||
* This does not necessarily return the FontMetrics from the Graphics.
|
||||
*
|
||||
* @param c JComponent requesting FontMetrics, may be null
|
||||
* @param g Graphics Graphics
|
||||
* @return the font metrics
|
||||
*/
|
||||
public static FontMetrics getFontMetrics(JComponent c, Graphics g) {
|
||||
return getFontMetrics(c, g, g.getFont());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FontMetrics for the specified Font. This method is used when
|
||||
* a Graphics is available, typically when painting. If a Graphics is not
|
||||
* available the JComponent method of the same name should be used.
|
||||
* <p>
|
||||
* Callers should pass in a non-null JComonent, the exception to this is if
|
||||
* a JComponent is not readily available at the time of painting.
|
||||
* <p>
|
||||
* This does not necessarily return the FontMetrics from the Graphics.
|
||||
*
|
||||
* @param c Graphics Graphics
|
||||
* @param g the g
|
||||
* @param font Font to get FontMetrics for
|
||||
* @return the font metrics
|
||||
*/
|
||||
public static FontMetrics getFontMetrics(JComponent c, Graphics g,
|
||||
Font font) {
|
||||
if (c != null)
|
||||
// Note: We assume that we're using the FontMetrics
|
||||
// from the widget to layout out text, otherwise we can get
|
||||
// mismatches when printing.
|
||||
return c.getFontMetrics(font);
|
||||
return Toolkit.getDefaultToolkit().getFontMetrics(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the passed in String.
|
||||
*
|
||||
* @param c JComponent that will display the string, may be null
|
||||
* @param fm FontMetrics used to measure the String width
|
||||
* @param string String to get the width of
|
||||
* @return the int
|
||||
*/
|
||||
public static int stringWidth(JComponent c, FontMetrics fm, String string) {
|
||||
return fm.stringWidth(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the string at the specified location.
|
||||
*
|
||||
* @param c JComponent that will display the string, may be null
|
||||
* @param g Graphics to draw the text to
|
||||
* @param text String to display
|
||||
* @param x X coordinate to draw the text at
|
||||
* @param y Y coordinate to draw the text at
|
||||
*/
|
||||
public static void drawString(JComponent c, Graphics g, String text,
|
||||
int x, int y) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.drawString(text, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the string at the specified location underlining the specified
|
||||
* character.
|
||||
*
|
||||
* @param c JComponent that will display the string, may be null
|
||||
* @param g Graphics to draw the text to
|
||||
* @param text String to display
|
||||
* @param underlinedIndex Index of a character in the string to underline
|
||||
* @param x X coordinate to draw the text at
|
||||
* @param y Y coordinate to draw the text at
|
||||
*/
|
||||
public static void drawStringUnderlineCharAt(JComponent c, Graphics g,
|
||||
String text, int underlinedIndex, int x, int y) {
|
||||
drawString(c, g, text, x, y);
|
||||
if (underlinedIndex >= 0 && underlinedIndex < text.length()) {
|
||||
// PENDING: this needs to change.
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int underlineRectX = x + stringWidth(c,
|
||||
fm, text.substring(0, underlinedIndex));
|
||||
int underlineRectY = y;
|
||||
int underlineRectWidth = fm.charWidth(text.
|
||||
charAt(underlinedIndex));
|
||||
int underlineRectHeight = 1;
|
||||
g.fillRect(underlineRectX, underlineRectY + 1,
|
||||
underlineRectWidth, underlineRectHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips the passed in String to the space provided.
|
||||
*
|
||||
* @param c JComponent that will display the string, may be null
|
||||
* @param fm FontMetrics used to measure the String width
|
||||
* @param string String to display
|
||||
* @param availTextWidth Amount of space that the string can be drawn in
|
||||
* @return Clipped string that can fit in the provided space.
|
||||
*/
|
||||
public static String clipStringIfNecessary(JComponent c, FontMetrics fm,
|
||||
String string, int availTextWidth) {
|
||||
if ((string == null) || (string.equals("")))
|
||||
return "";
|
||||
int textWidth = stringWidth(c, fm, string);
|
||||
if (textWidth > availTextWidth)
|
||||
return clipString(c, fm, string, availTextWidth);
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips the passed in String to the space provided. NOTE: this assumes the
|
||||
* string does not fit in the available space.
|
||||
*
|
||||
* @param c JComponent that will display the string, may be null
|
||||
* @param fm FontMetrics used to measure the String width
|
||||
* @param string String to display
|
||||
* @param availTextWidth Amount of space that the string can be drawn in
|
||||
* @return Clipped string that can fit in the provided space.
|
||||
*/
|
||||
public static String clipString(JComponent c, FontMetrics fm,
|
||||
String string, int availTextWidth) {
|
||||
// c may be null here.
|
||||
String clipString = "...";
|
||||
int width = stringWidth(c, fm, clipString);
|
||||
// NOTE: This does NOT work for surrogate pairs and other fun
|
||||
// stuff
|
||||
int nChars = 0;
|
||||
for (int max = string.length(); nChars < max; nChars++) {
|
||||
width += fm.charWidth(string.charAt(nChars));
|
||||
if (width > availTextWidth)
|
||||
break;
|
||||
}
|
||||
string = string.substring(0, nChars) + clipString;
|
||||
return string;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* NinePatchHelper.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* NinePatch图辅助工厂类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2011-12-22
|
||||
* @version 1.0
|
||||
*/
|
||||
public class NinePatchHelper {
|
||||
|
||||
/**
|
||||
* Creates the nine patch.
|
||||
*
|
||||
* @param fileUrl the file url
|
||||
* @param convert the convert
|
||||
* @return the nine patch
|
||||
* @see NinePatch#load(URL, boolean)
|
||||
*/
|
||||
public static NinePatch createNinePatch(URL fileUrl, boolean convert) {
|
||||
try {
|
||||
return NinePatch.load(fileUrl, convert);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the nine patch.
|
||||
*
|
||||
* @param stream the stream
|
||||
* @param is9Patch the is9 patch
|
||||
* @param convert the convert
|
||||
* @return the nine patch
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
* @see NinePatch#load(InputStream, boolean, boolean)
|
||||
*/
|
||||
public static NinePatch createNinePatch(InputStream stream, boolean is9Patch, boolean convert) throws IOException {
|
||||
return NinePatch.load(stream, is9Patch, convert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the nine patch.
|
||||
*
|
||||
* @param image the image
|
||||
* @param is9Patch the is9 patch
|
||||
* @param convert the convert
|
||||
* @return the nine patch
|
||||
* @see NinePatch#load(BufferedImage, boolean, boolean)
|
||||
*/
|
||||
public static NinePatch createNinePatch(BufferedImage image, boolean is9Patch, boolean convert) {
|
||||
return NinePatch.load(image, is9Patch, convert);
|
||||
}
|
||||
}
|
66
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/UI.java
Normal file
66
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/UI.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.DimensionUIResource;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class UI {
|
||||
|
||||
protected static void put(String key, int i) {
|
||||
UIManager.put(key, i);
|
||||
}
|
||||
|
||||
protected static void put(String key, boolean b) {
|
||||
UIManager.put(key, b);
|
||||
}
|
||||
|
||||
protected static void put(String key, Color c) {
|
||||
UIManager.put(key, new ColorUIResource(c));
|
||||
}
|
||||
|
||||
protected static void put(String key, Border b) {
|
||||
UIManager.put(key, new BorderUIResource(b));
|
||||
}
|
||||
|
||||
protected static void putDim(String key, int w, int h) {
|
||||
UIManager.put(key, new DimensionUIResource(h, h));
|
||||
}
|
||||
|
||||
protected static void putInsets(String key, int top, int left, int bottom, int right) {
|
||||
UIManager.put(key, new InsetsUIResource(top, left, bottom, right));
|
||||
}
|
||||
|
||||
protected static void putBorder(String key) {
|
||||
UIManager.put(key, BorderFactory.createEmptyBorder());
|
||||
}
|
||||
|
||||
protected static void putBorder(String key, int top, int left, int bottom, int right) {
|
||||
UIManager.put(key, new BorderUIResource(BorderFactory.createEmptyBorder(top, left, bottom, right)));
|
||||
}
|
||||
|
||||
protected static void putColor(String key, int r, int g, int b) {
|
||||
put(key, new Color(r, g, b));
|
||||
}
|
||||
|
||||
protected static void putColor(String key, int r, int g, int b, int a) {
|
||||
put(key, new Color(r, g, b, a));
|
||||
}
|
||||
|
||||
protected static void put(String key, Class c) {
|
||||
UIManager.put(key, c.getName());
|
||||
}
|
||||
}
|
147
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/WinUtils.java
Normal file
147
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/WinUtils.java
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* WinUtils.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* The Class WinUtils.
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsGraphicsUtils
|
||||
*/
|
||||
public class WinUtils {
|
||||
//* copy from WindowsLookAndFeel START 未做修改
|
||||
// Toggle flag for drawing the mnemonic state
|
||||
|
||||
/**
|
||||
* The is mnemonic hidden.
|
||||
*/
|
||||
private static boolean isMnemonicHidden = true;
|
||||
|
||||
/**
|
||||
* Gets the state of the hide mnemonic flag. This only has meaning if this
|
||||
* feature is supported by the underlying OS.
|
||||
*
|
||||
* @return true if mnemonics are hidden, otherwise, false
|
||||
* @see #setMnemonicHidden
|
||||
* @since 1.4
|
||||
*/
|
||||
public static boolean isMnemonicHidden() {
|
||||
if (UIManager.getBoolean("Button.showMnemonics") == true)
|
||||
// Do not hide mnemonics if the UI defaults do not support this
|
||||
isMnemonicHidden = false;
|
||||
return isMnemonicHidden;
|
||||
}
|
||||
//* copy from WindowsLookAndFeel END
|
||||
|
||||
//* copy from WindowsGraphicsUtils START (modified by jack jiang)
|
||||
/**
|
||||
* Renders a text String in Windows without the mnemonic. This is here
|
||||
* because the WindowsUI hiearchy doesn't match the Component heirarchy. All
|
||||
* the overriden paintText methods of the ButtonUI delegates will call this
|
||||
* static method.
|
||||
* <p>
|
||||
*
|
||||
* @param g Graphics context
|
||||
* @param b Current button to render
|
||||
* @param textRect Bounding rectangle to render the text.
|
||||
* @param text String to render
|
||||
* @param textShiftOffset the text shift offset
|
||||
*/
|
||||
public static void paintText(Graphics g, AbstractButton b,
|
||||
Rectangle textRect, String text,
|
||||
int textShiftOffset) {
|
||||
FontMetrics fm = MySwingUtilities2.getFontMetrics(b, g);
|
||||
|
||||
int mnemIndex = b.getDisplayedMnemonicIndex();
|
||||
// W2K Feature: Check to see if the Underscore should be rendered.
|
||||
if (isMnemonicHidden() == true)
|
||||
mnemIndex = -1;
|
||||
paintClassicText(b, g, textRect.x + textShiftOffset,
|
||||
textRect.y + fm.getAscent() + textShiftOffset,
|
||||
text, mnemIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint classic text.
|
||||
*
|
||||
* @param b the b
|
||||
* @param g the g
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param text the text
|
||||
* @param mnemIndex the mnem index
|
||||
*/
|
||||
static void paintClassicText(AbstractButton b, Graphics g, int x, int y,
|
||||
String text, int mnemIndex) {
|
||||
ButtonModel model = b.getModel();
|
||||
|
||||
/* Draw the Text */
|
||||
Color color = b.getForeground();
|
||||
if (model.isEnabled()) {
|
||||
/**
|
||||
* * paint the text normally
|
||||
*/
|
||||
if (!(b instanceof JMenuItem && model.isArmed())
|
||||
&& !(b instanceof JMenu && (model.isSelected() || model.isRollover())))
|
||||
/* We shall not set foreground color for selected menu or
|
||||
* armed menuitem. Foreground must be set in appropriate
|
||||
* Windows* class because these colors passes from
|
||||
* BasicMenuItemUI as protected fields and we can't
|
||||
* reach them from this class */
|
||||
g.setColor(b.getForeground());
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y);
|
||||
} else {
|
||||
/**
|
||||
* * paint the text disabled **
|
||||
*/
|
||||
color = UIManager.getColor("Button.shadow");
|
||||
Color shadow = UIManager.getColor("Button.disabledShadow");
|
||||
if (model.isArmed())
|
||||
color = UIManager.getColor("Button.disabledForeground");
|
||||
else {
|
||||
if (shadow == null)
|
||||
shadow = b.getBackground().darker();
|
||||
g.setColor(shadow);
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x + 1, y + 1);
|
||||
}
|
||||
if (color == null)
|
||||
color = b.getBackground().brighter();
|
||||
g.setColor(color);
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y);
|
||||
|
||||
}
|
||||
}
|
||||
//* copy from WindowsGraphicsUtils END (modified by jack jiang)
|
||||
|
||||
//* copy from WindowsGraphicsUtils START
|
||||
/**
|
||||
* 是否组件的排列方向是从左到右.
|
||||
*
|
||||
* @param c the c
|
||||
* @return true, if is left to right
|
||||
*/
|
||||
public static boolean isLeftToRight(Component c) {
|
||||
return c.getComponentOrientation().isLeftToRight();
|
||||
}
|
||||
//* copy from WindowsGraphicsUtils END
|
||||
}
|
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEButtonUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.button;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* JButton的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsButtonUI
|
||||
*/
|
||||
public class BEButtonUI extends BasicButtonUI {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("button");
|
||||
|
||||
private final static BEButtonUI INSTANCE = new BEButtonUI();
|
||||
|
||||
/**
|
||||
* The dashed rect gap x.
|
||||
*/
|
||||
protected int dashedRectGapX;
|
||||
|
||||
/**
|
||||
* The dashed rect gap y.
|
||||
*/
|
||||
protected int dashedRectGapY;
|
||||
|
||||
/**
|
||||
* The dashed rect gap width.
|
||||
*/
|
||||
protected int dashedRectGapWidth;
|
||||
|
||||
/**
|
||||
* The dashed rect gap height.
|
||||
*/
|
||||
protected int dashedRectGapHeight;
|
||||
|
||||
/**
|
||||
* The focus color.
|
||||
*/
|
||||
protected Color focusColor;
|
||||
|
||||
/**
|
||||
* The defaults_initialized.
|
||||
*/
|
||||
private boolean defaults_initialized = false;
|
||||
|
||||
// ********************************
|
||||
// Create PLAF
|
||||
// ********************************
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
if (c instanceof CustomButton)
|
||||
return new CustomButtonUI();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Defaults
|
||||
// ********************************
|
||||
@Override
|
||||
protected void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
|
||||
|
||||
if (!defaults_initialized) {
|
||||
String pp = getPropertyPrefix();
|
||||
dashedRectGapX = UIManager.getInt(pp + "dashedRectGapX");
|
||||
dashedRectGapY = UIManager.getInt(pp + "dashedRectGapY");
|
||||
dashedRectGapWidth = UIManager.getInt(pp + "dashedRectGapWidth");
|
||||
dashedRectGapHeight = UIManager.getInt(pp + "dashedRectGapHeight");
|
||||
focusColor = UIManager.getColor(pp + "focus");
|
||||
defaults_initialized = true;
|
||||
}
|
||||
|
||||
{
|
||||
LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults(AbstractButton b) {
|
||||
super.uninstallDefaults(b);
|
||||
defaults_initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the focus color.
|
||||
*
|
||||
* @return the focus color
|
||||
*/
|
||||
protected Color getFocusColor() {
|
||||
return focusColor;
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Paint Methods
|
||||
// ********************************
|
||||
@Override
|
||||
protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
|
||||
// focus painted same color as text on Basic??
|
||||
int width = b.getWidth();
|
||||
int height = b.getHeight();
|
||||
g.setColor(getFocusColor());
|
||||
|
||||
//** modified by jb2011:绘制虚线方法改成可以设置虚线步进的方法,步进设为2则更好看一点
|
||||
// BasicGraphicsUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY,
|
||||
// width - dashedRectGapWidth, height - dashedRectGapHeight);
|
||||
// 绘制虚线框
|
||||
BEUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY,
|
||||
width - dashedRectGapWidth, height - dashedRectGapHeight);
|
||||
// 绘制虚线框的半透明白色立体阴影(半透明的用处在于若隐若现的效果比纯白要来的柔和的多)
|
||||
g.setColor(new Color(255, 255, 255, 50));
|
||||
// 立体阴影就是向右下偏移一个像素实现的
|
||||
BEUtils.drawDashedRect(g, dashedRectGapX + 1, dashedRectGapY + 1,
|
||||
width - dashedRectGapWidth, height - dashedRectGapHeight);
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Layout Methods
|
||||
// ********************************
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
Dimension d = super.getPreferredSize(c);
|
||||
|
||||
/* Ensure that the width and height of the button is odd,
|
||||
* to allow for the focus line if focus is painted
|
||||
*/
|
||||
AbstractButton b = (AbstractButton) c;
|
||||
if (d != null && b.isFocusPainted()) {
|
||||
if (d.width % 2 == 0)
|
||||
d.width += 1;
|
||||
if (d.height % 2 == 0)
|
||||
d.height += 1;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/* These rectangles/insets are allocated once for all
|
||||
* ButtonUI.paint() calls. Re-using rectangles rather than
|
||||
* allocating them in each paint call substantially reduced the time
|
||||
* it took paint to run. Obviously, this method can't be re-entered.
|
||||
*/
|
||||
// private static Rectangle viewRect = new Rectangle();
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
paintXPButtonBackground(g, c);
|
||||
super.paint(g, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint xp button background.
|
||||
*
|
||||
* @param nomalColor the nomal color
|
||||
* @param g the g
|
||||
* @param c the c
|
||||
*/
|
||||
public static void paintXPButtonBackground(Graphics g, JComponent c) {
|
||||
AbstractButton b = (AbstractButton) c;
|
||||
boolean toolbar = b.getParent() instanceof JToolBar;
|
||||
|
||||
if (b.isContentAreaFilled()) {
|
||||
ButtonModel model = b.getModel();
|
||||
Dimension d = c.getSize();
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
int dw = d.width;
|
||||
int dh = d.height;
|
||||
|
||||
Border border = c.getBorder();
|
||||
Insets insets;
|
||||
if (border != null)
|
||||
// Note: The border may be compound, containing an outer
|
||||
// opaque border (supplied by the application), plus an
|
||||
// inner transparent margin border. We want to size the
|
||||
// background to fill the transparent part, but stay
|
||||
// inside the opaque part.
|
||||
insets = BEButtonUI.getOpaqueInsets(border, c);
|
||||
else
|
||||
insets = c.getInsets();
|
||||
if (insets != null) {
|
||||
dx += insets.left;
|
||||
dy += insets.top;
|
||||
dw -= (insets.left + insets.right);
|
||||
dh -= (insets.top + insets.bottom);
|
||||
}
|
||||
|
||||
if (toolbar)
|
||||
//此状态下JToggleButton和JButton使用各自的背景实现,2012-10-16前无论是不是JToggleButton都是使用该种实是不太合理的
|
||||
if (model.isRollover() || model.isPressed())
|
||||
if (c instanceof JToggleButton)
|
||||
BEToggleButtonUI.ICON_9.get("rollover").draw((Graphics2D) g, dx, dy, dw, dh);
|
||||
else
|
||||
ICON_9.get("pressed").draw((Graphics2D) g, dx, dy, dw, dh);
|
||||
else if (model.isSelected())
|
||||
BEToggleButtonUI.ICON_9.get("selected").draw((Graphics2D) g, dx, dy, dw, dh);
|
||||
else {
|
||||
//TODO 其它状态下的按钮背景样式需要完善,要不然看起来太硬!
|
||||
// skin.paintSkin(g, dx, dy, dw, dh, state);
|
||||
}
|
||||
else {
|
||||
//TODO 其它状态下的按钮背景样式需要完善,要不然看起来太硬!
|
||||
String key;
|
||||
if (model.isArmed() && model.isPressed() || model.isSelected())
|
||||
key = "pressed";
|
||||
else if (!model.isEnabled())
|
||||
key = "disabled";
|
||||
else if (model.isRollover())
|
||||
key = "rollover";
|
||||
else
|
||||
key = "normal";
|
||||
ICON_9.get(key).draw((Graphics2D) g, dx, dy, dw, dh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns - b.getBorderInsets(c) if border is opaque - null if border is
|
||||
* completely non-opaque - somewhere inbetween if border is compound and
|
||||
* outside border is opaque and inside isn't
|
||||
*
|
||||
* @param b the b
|
||||
* @param c the c
|
||||
* @return the opaque insets
|
||||
*/
|
||||
private static Insets getOpaqueInsets(Border b, Component c) {
|
||||
if (b == null)
|
||||
return null;
|
||||
if (b.isBorderOpaque())
|
||||
return b.getBorderInsets(c);
|
||||
else if (b instanceof CompoundBorder) {
|
||||
CompoundBorder cb = (CompoundBorder) b;
|
||||
Insets iOut = getOpaqueInsets(cb.getOutsideBorder(), c);
|
||||
if (iOut != null && iOut.equals(cb.getOutsideBorder().getBorderInsets(c))) {
|
||||
// Outside border is opaque, keep looking
|
||||
Insets iIn = getOpaqueInsets(cb.getInsideBorder(), c);
|
||||
if (iIn == null)
|
||||
// Inside is non-opaque, use outside insets
|
||||
return iOut;
|
||||
else
|
||||
// Found non-opaque somewhere in the inside (which is
|
||||
// also compound).
|
||||
return new Insets(iOut.top + iIn.top, iOut.left + iIn.left,
|
||||
iOut.bottom + iIn.bottom, iOut.right + iIn.right);
|
||||
} else
|
||||
// Outside is either all non-opaque or has non-opaque
|
||||
// border inside another compound border
|
||||
return iOut;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class BEEmptyBorder extends EmptyBorder implements UIResource {
|
||||
|
||||
public BEEmptyBorder(Insets m) {
|
||||
super(m.top + 2, m.left + 2, m.bottom + 2, m.right + 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return getBorderInsets(c, getBorderInsets());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
insets = super.getBorderInsets(c, insets);
|
||||
|
||||
Insets margin = null;
|
||||
if (c instanceof AbstractButton) {
|
||||
Insets m = ((AbstractButton) c).getMargin();
|
||||
// if this is a toolbar button then ignore getMargin()
|
||||
// and subtract the padding added by the constructor
|
||||
if (c.getParent() instanceof JToolBar
|
||||
&& !(c instanceof JRadioButton)
|
||||
&& !(c instanceof JCheckBox)
|
||||
&& m instanceof InsetsUIResource) {
|
||||
insets.top -= 2;
|
||||
insets.left -= 2;
|
||||
insets.bottom -= 2;
|
||||
insets.right -= 2;
|
||||
} else
|
||||
margin = m;
|
||||
} else if (c instanceof JToolBar)
|
||||
margin = ((JToolBar) c).getMargin();
|
||||
else if (c instanceof JTextComponent)
|
||||
margin = ((JTextComponent) c).getMargin();
|
||||
if (margin != null) {
|
||||
insets.top = margin.top + 2;
|
||||
insets.left = margin.left + 2;
|
||||
insets.bottom = margin.bottom + 2;
|
||||
insets.right = margin.right + 2;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEToggleButtonUI.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.button;
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicToggleButtonUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.utils.MySwingUtilities2;
|
||||
|
||||
/**
|
||||
* JToggleButton的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsToggleButtonUI
|
||||
*/
|
||||
public class BEToggleButtonUI extends BasicToggleButtonUI {
|
||||
|
||||
protected static final Icon9Factory ICON_9 = new Icon9Factory("toggle_button");
|
||||
|
||||
private static final BEToggleButtonUI INSTANCE = new BEToggleButtonUI();
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
//* 由Jack Jiang于2012-10-12日加入:重写本方法的目的是使得JToggleButton不填充
|
||||
//* BasicToggleButtonUI里的白色距形区,否则在JToolBar上时会因该白色距形区的存
|
||||
//* 在而使得与BEToolBarUI的渐变背景不协调(丑陋的创可贴效果),实际上
|
||||
//* WindowsToolButtonUI里有同名方法里也是它样处理的,详情参见WindowsToolButtonUI
|
||||
@Override
|
||||
protected void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
|
||||
}
|
||||
|
||||
// ********************************
|
||||
// Paint Methods
|
||||
// ********************************
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
BEButtonUI.paintXPButtonBackground(g, c);
|
||||
super.paint(g, c);
|
||||
}
|
||||
|
||||
//修改的目的是让它在获得焦点(或说点中时)改变前景色,可惜父类中没有实现它,只能自已来解决了
|
||||
/**
|
||||
* As of Java 2 platform v 1.4 this method should not be used or overriden.
|
||||
* Use the paintText method which takes the AbstractButton argument.
|
||||
*
|
||||
* @param g the g
|
||||
* @param c the c
|
||||
* @param textRect the text rect
|
||||
* @param text the text
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicToggleButtonUI#paintText(java.awt.Graphics,
|
||||
* javax.swing.JComponent, java.awt.Rectangle, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
|
||||
AbstractButton b = (AbstractButton) c;
|
||||
ButtonModel model = b.getModel();
|
||||
FontMetrics fm = MySwingUtilities2.getFontMetrics(c, g);
|
||||
int mnemonicIndex = b.getDisplayedMnemonicIndex();
|
||||
|
||||
if (model.isEnabled()) {
|
||||
if (model.isSelected())
|
||||
g.setColor(UIManager.getColor(getPropertyPrefix() + "focus"));
|
||||
else
|
||||
g.setColor(b.getForeground());
|
||||
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(c, g, text, mnemonicIndex,
|
||||
textRect.x + getTextShiftOffset(),
|
||||
textRect.y + fm.getAscent() + getTextShiftOffset());
|
||||
} else {
|
||||
g.setColor(b.getBackground().brighter());
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(c, g, text, mnemonicIndex,
|
||||
textRect.x, textRect.y + fm.getAscent());
|
||||
g.setColor(b.getBackground().darker());
|
||||
MySwingUtilities2.drawStringUnderlineCharAt(c, g, text, mnemonicIndex,
|
||||
textRect.x - 1, textRect.y + fm.getAscent() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Method signature defined here overriden in subclasses. Perhaps this class
|
||||
* should be abstract?
|
||||
*/
|
||||
@Override
|
||||
protected void paintFocus(Graphics g, AbstractButton b,
|
||||
Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
|
||||
Rectangle bound = b.getVisibleRect();
|
||||
//决定焦点要制的位置(当前实现是往内缩3个像素,与当前按钮背景配合)
|
||||
final int delta = 3;
|
||||
int x = bound.x + delta, y = bound.y + delta, w = bound.width - delta * 2, h = bound.height - delta * 2;
|
||||
|
||||
//绘制焦点虚线框
|
||||
g.setColor(UIManager.getColor("ToggleButton.focusLine"));//*~ 这是Jack Jiang自定义的属性哦
|
||||
BEUtils.drawDashedRect(g, x, y, w, h, 17, 17, 2, 2);
|
||||
//再绘制焦点虚线框的立体高亮阴影,以便形成立体感
|
||||
g.setColor(UIManager.getColor("ToggleButton.focusLineHilight"));//*~ 这是Jack Jiang自定义的属性哦
|
||||
BEUtils.drawDashedRect(g, x + 1, y + 1, w, h, 17, 17, 2, 2);
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf;
|
||||
package org.jackhuang.hmcl.laf.button;
|
||||
|
||||
import java.awt.Color;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
@ -23,7 +23,7 @@ import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ConstomButton extends javax.swing.JButton {
|
||||
public class CustomButton extends javax.swing.JButton {
|
||||
public Color normalFg = GraphicsUtils.getWebColorWithAlpha("DDDDDD6F"), normalBg = GraphicsUtils.getWebColorWithAlpha("DDDDDD6F"),
|
||||
prelightFg = GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"), prelightBg = GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"),
|
||||
activeFg = GraphicsUtils.getWebColorWithAlpha("EAEDF83F"), activeBg = GraphicsUtils.getWebColorWithAlpha("EAEDF83F");
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.button;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
import org.jackhuang.hmcl.laf.button.BEButtonUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class CustomButtonUI extends BasicButtonUI {
|
||||
|
||||
private static final String DEFAULT_NORMAL = "D5D5D5";
|
||||
private static final Color[] DEFAULT_NORMAL_FG = new Color[] {
|
||||
GraphicsUtils.getWebColor(DEFAULT_NORMAL),
|
||||
GraphicsUtils.getWebColor(DEFAULT_NORMAL)
|
||||
};
|
||||
private static final String DEFAULT_PRELIGHT = "A9A9A9";
|
||||
private static final Color[] DEFAULT_PRELIGHT_FG = new Color[] {
|
||||
GraphicsUtils.getWebColor(DEFAULT_PRELIGHT),
|
||||
GraphicsUtils.getWebColor(DEFAULT_PRELIGHT)
|
||||
};
|
||||
private static final String DEFAULT_ACTIVE = "222222";
|
||||
private static final Color[] DEFAULT_ACTIVE_FG = new Color[] {
|
||||
GraphicsUtils.getWebColor(DEFAULT_ACTIVE),
|
||||
GraphicsUtils.getWebColor(DEFAULT_ACTIVE)
|
||||
};
|
||||
|
||||
private static final Color[] DISABLED_BG = new Color[] {
|
||||
GraphicsUtils.getWebColor("E3EFE9"),
|
||||
GraphicsUtils.getMidWebColor("E3EFE9", "DFE2E6"),
|
||||
GraphicsUtils.getWebColor("DFE2E6"),
|
||||
GraphicsUtils.getMidWebColor("DFE2E6", "D6D9DF"),
|
||||
GraphicsUtils.getWebColor("D6D9DF"),
|
||||
GraphicsUtils.getWebColor("D6D9DF"),
|
||||
GraphicsUtils.getMidWebColor("D6D9DF", "D8DBE1"),
|
||||
GraphicsUtils.getWebColor("D8DBE1"),
|
||||
GraphicsUtils.getWebColor("DADDE3")
|
||||
};
|
||||
private static final Color[] DISABLED_FG = new Color[] {
|
||||
GraphicsUtils.getWebColor("C9CCD2"),
|
||||
GraphicsUtils.getWebColor("C9CCD2"),
|
||||
GraphicsUtils.getWebColor("BCBFC5"),
|
||||
GraphicsUtils.getWebColor("BCBFC5")
|
||||
};
|
||||
|
||||
private static boolean processCustomButton(final CustomButton c, int add) {
|
||||
if (c.drawPercent == 0 || c.drawPercent == 100) {
|
||||
Timer t = new Timer(1, null);
|
||||
t.addActionListener(x -> {
|
||||
c.drawPercent += add;
|
||||
if (c.drawPercent > 100 && add > 0) {
|
||||
c.drawPercent = 100;
|
||||
t.stop();
|
||||
} else if (c.drawPercent < 0 && add < 0) {
|
||||
c.drawPercent = 0;
|
||||
t.stop();
|
||||
} else
|
||||
c.updateUI();
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent component) {
|
||||
CustomButton c = (CustomButton) component;
|
||||
ButtonModel model = c.getModel();
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
Color[] fg, bg;
|
||||
if (model.isPressed()) {
|
||||
fg = new Color[] { c.activeFg, c.activeFg };
|
||||
bg = new Color[] { c.activeFg, c.activeFg };
|
||||
} else if (!c.isEnabled())
|
||||
return;
|
||||
else if (model.isRollover()) {
|
||||
if (!processCustomButton(c, 1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[] { fgs, fgs };
|
||||
bg = new Color[] { bgs, bgs };
|
||||
} else {
|
||||
if (!processCustomButton(c, -1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[] { fgs, fgs };
|
||||
bg = new Color[] { bgs, bgs };
|
||||
}
|
||||
|
||||
int radix = c.radix;
|
||||
int x = 0, y = 0, w = c.getWidth(), h = c.getHeight();
|
||||
|
||||
g2.setColor(fg[0]);
|
||||
RoundRectangle2D fgshape = new RoundRectangle2D.Float(x, y, w, h, radix, radix);
|
||||
g2.draw(fgshape);
|
||||
g2.setColor(bg[0]);
|
||||
RoundRectangle2D bgshape = new RoundRectangle2D.Float(x, y, w, h, radix, radix);
|
||||
g2.fill(bgshape);
|
||||
|
||||
super.paint(g, c);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.button;
|
||||
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.basic.BasicBorders.MarginBorder;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JButton相关ui属性设定
|
||||
put("Button.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
//Button.foreground的设定不起效,这可能是LNF里的bug,因NLLookAndFeel
|
||||
//是继承自它们所以暂时无能为力,就这么的吧,以后再说
|
||||
put("Button.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
//以下属性将决定按钮获得焦点时的焦点虚线框的绘制偏移量哦
|
||||
put("Button.dashedRectGapX", 3);
|
||||
put("Button.dashedRectGapY", 3);
|
||||
put("Button.dashedRectGapWidth", 6);
|
||||
put("Button.dashedRectGapHeight", 6);
|
||||
|
||||
put("ButtonUI", BEButtonUI.class);
|
||||
putInsets("Button.margin", 2, 5, 2, 5);
|
||||
//此border可以与Button.margin连合使用,而者之和即查整个Button的内衬哦
|
||||
UIManager.put("Button.border", new BEButtonUI.BEEmptyBorder(new Insets(3, 3, 3, 3)));
|
||||
//获得焦点时的虚线框颜色
|
||||
putColor("Button.focus", 130, 130, 130);
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JToggleButton相关ui属性设定
|
||||
//注意:本属性不要与ToggleButton.border混用,因为没有它的优先级高,
|
||||
//另本参数如用InsetsUIResource则不会有效果,具体原因待查(本属性也将决定toolbar的整体高度和宽度哦)
|
||||
putInsets("ToggleButton.margin", 3, 11, 3, 11);//4, 8, 4, 8));////4, 12, 4, 12));
|
||||
put("ToggleButton.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("ToggleButton.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
//用于ToggleButon被选中时的前景色
|
||||
//注:在原WindowsLookAndFeel中,本属性存在(值是Color(0,0,0,))但在UI里没有用到
|
||||
//,此处被jb2011定义为“选中时的前景色”,当然也可以自已定名称,参见 NLWindowsToggleButtonUI2.paintText(..)
|
||||
put("ToggleButton.focus", BeautyEyeLNFHelper.commonForegroundColor);// Color.white
|
||||
put("ToggleButtonUI", BEToggleButtonUI.class);
|
||||
//以下设置对ToggleButton在不加入到JToolBar时是有效果的哦!!!!!!!!!!!
|
||||
// UIManager.put("ToggleButton.margin",new InsetsUIResource(2, 30, 2, 30));
|
||||
put("ToggleButton.border", new MarginBorder());
|
||||
/* ~~注:这个属性是Jack Jiang为了更好的ui效果自已加的属性:焦点虚线的颜色 */
|
||||
put("ToggleButton.focusLine", BeautyEyeLNFHelper.commonFocusedBorderColor.darker());
|
||||
/* ~~注:这个属性是Jack Jiang为了更好的ui效果自已加的属性:焦点虚线的高亮立体阴影颜色 */
|
||||
putColor("ToggleButton.focusLineHilight", 240, 240, 240);
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEComboBoxRenderer.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.combox;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||
import org.jackhuang.hmcl.laf.menu.BEMenuUI;
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
|
||||
/**
|
||||
* JComboBox组件下拉选项的render默认实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-07-05
|
||||
* @see BEComboBoxUI
|
||||
*/
|
||||
public class BEComboBoxRenderer extends BasicComboBoxRenderer {
|
||||
|
||||
/**
|
||||
* 当前下拉框里的item是否被选中:用于是否要将背景填充选中样式时使用.
|
||||
*/
|
||||
private boolean selected = false;
|
||||
|
||||
/**
|
||||
* 记下本render对应的JComboBox的UI.
|
||||
*/
|
||||
private BEComboBoxUI comboBoxUI = null;
|
||||
|
||||
public BEComboBoxRenderer(BEComboBoxUI ui) {
|
||||
super();
|
||||
this.comboBoxUI = ui;
|
||||
//设置成透明背景则意味着不需要背景填充,但本类中的应用场景有点特殊
|
||||
//——默认的render的UI里不需要绘制背景的情况下本类才可进行NinePatch图作为背景进行填充
|
||||
setOpaque(false);
|
||||
//TODO 此border(render的内衬)可以作为一个UIManager的属性哦,方便以后设置
|
||||
//注:此内衬是决定列表单元间的上下左右空白的关键哦!
|
||||
setBorder(BorderFactory.createEmptyBorder(5, 4, 5, 8));//此设置是与Combox.border UI属性配合哦
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicComboBoxRenderer#getListCellRendererComponent
|
||||
* (javax.swing.JList, java.lang.Object, int, boolean, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list,
|
||||
Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Component c = super.getListCellRendererComponent(list,
|
||||
value, index, isSelected, cellHasFocus);
|
||||
//add by jb2011:保存选中状态
|
||||
this.selected = isSelected;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 按理说本方法中的是否选中背景填充实现逻辑在Render的UI中实现最为合理,但由于
|
||||
* 本类就是处理于UI实现中,所以容易产生冲突,故而不适宜自定义Ui实现,干脆硬编码则更直接
|
||||
*/
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
//当下拉选项弹出时 且 该item是被选中时才需要把背景填充成选中样式
|
||||
if (comboBoxUI.isPopupVisible(null) && selected)
|
||||
BEMenuUI.drawSelectedBackground(g, 0, 0, this.getWidth(), this.getHeight());
|
||||
//下拉选项未弹出时JComboBox的背景样式
|
||||
//按理说,本类已设置成透明而无须填充背景,但本应用场景中,只能在默认Ui不填充背景的情况下才
|
||||
//能完成自定义NinePatch背景的填充。见 ComponentUI.update(Graphics g, JComponent c)方法
|
||||
|
||||
//注意:本组件已经被设置成opaque=false即透明,否则本方法还会填充默认背景,那么选中时的
|
||||
//N9图背景因先绘将会被覆盖哦。所以要使用N9图作为选中时的背景则前提是本组件必须是透明
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
//copy from BasicComboBoxRenderer and modified by jb2011
|
||||
/**
|
||||
* A subclass of BasicComboBoxRenderer that implements UIResource.
|
||||
* BasicComboBoxRenderer doesn't implement UIResource directly so that
|
||||
* applications can safely override the cellRenderer property with
|
||||
* BasicListCellRenderer subclasses.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with future Swing
|
||||
* releases. The current serialization support is appropriate for short term
|
||||
* storage or RMI between applications running the same version of Swing. As
|
||||
* of 1.4, support for long term storage of all
|
||||
* JavaBeans<sup><font size="-2">TM</font></sup>
|
||||
* has been added to the <code>java.beans</code> package. Please see
|
||||
* {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
public static class UIResource extends BEComboBoxRenderer implements javax.swing.plaf.UIResource {
|
||||
|
||||
/**
|
||||
* Instantiates a new uI resource.
|
||||
*
|
||||
* @param ui the ui
|
||||
*/
|
||||
public UIResource(BEComboBoxUI ui) {
|
||||
super(ui);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEComboBoxUI.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.combox;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
import javax.swing.ComboBoxEditor;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicComboBoxEditor;
|
||||
import javax.swing.plaf.basic.BasicComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import javax.swing.plaf.basic.ComboPopup;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* JComboBox的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-06-30
|
||||
* @version 1.0
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsComboBoxUI
|
||||
*/
|
||||
public class BEComboBoxUI extends BasicComboBoxUI
|
||||
implements org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported, MouseListener {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("combo");
|
||||
private static final Dimension BTN_SIZE = new Dimension(17, 20);
|
||||
private final Dimension btnSize = new Dimension(BTN_SIZE);
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEComboBoxUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JComboBox的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JComboBox.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return comboBox != null
|
||||
&& (!(comboBox.getBorder() instanceof UIResource)
|
||||
|| !(comboBox.getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
|
||||
//2012-08-30*******************************************************【重要说明】 START 对应BEListUI中的【重要说明】
|
||||
//* 【重要说明】因BEListUI中为了使列表行单元高变的更高(在MyDefaultListCellRenderer.java中
|
||||
//* 像COmboxRender一样通过增到border不起效果,它可能是BasicListUI的设计缺陷,它要么取FixedCellHeight
|
||||
//* 固定值,要么取getPreferSize()即自动计算高度——它似乎是不计入border的,所以render设置border不起效)
|
||||
//* 所以只能为列表单元设置因定值:list.setFixedCellHeight(30),但它将影响Combox里的行高(也会变成30高)
|
||||
//* 所以此处要把列表UI中强制设定的30高针对Combox还原成自动计算(API中规定FixedCellHeight==-1即表示自动计算)
|
||||
popup.getList().setFixedCellHeight(-1);
|
||||
//**************************************************************** 【重要说明】 END
|
||||
|
||||
//* 以下代码由jb2011加入
|
||||
// comboBox.setMaximumRowCount(8);//这个最大行可以起效,但似乎它的行高指的是一个固定值而不是计算值,像本LNF里因cell本身行高就很高
|
||||
//即使设置了最大显示行,但是显示的并不是指定值,有待进一步研究
|
||||
//为下拉框的弹出弹加border,这样上下空白外一点好看一些
|
||||
// install the scrollpane border
|
||||
Container parent = popup.getList().getParent(); // should be viewport
|
||||
if (parent != null) {
|
||||
parent = parent.getParent(); // should be the scrollpane
|
||||
if (parent != null && parent instanceof JScrollPane)
|
||||
LookAndFeel.installBorder((JScrollPane) parent, "ComboBox.scrollPaneBorder");//*~ 注:这个属性是Jack Jiang仿照JTabel里的实现自已加的属性
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
comboBox.addMouseListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
comboBox.removeMouseListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the combox.
|
||||
*
|
||||
* @return the combox
|
||||
*/
|
||||
public JComboBox getCombox() {
|
||||
return this.comboBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 自定义下接框箭头按钮实现类
|
||||
*/
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
JButton button = new JButton() {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (comboBox.isEditable())
|
||||
ICON_9.getWithComboState("", comboBox.isEnabled(), mouseDown, mouseInside)
|
||||
.draw((Graphics2D) g, 0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
button.addMouseListener(this);
|
||||
button.setMinimumSize(BTN_SIZE);
|
||||
button.setPreferredSize(BTN_SIZE);
|
||||
button.setMargin(new Insets(0, 0, 0, 0));
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
hasFocus = comboBox.hasFocus();
|
||||
ListCellRenderer renderer = comboBox.getRenderer();
|
||||
Rectangle r = new Rectangle(0, 0, comboBox.getWidth(), comboBox.getHeight());
|
||||
paintCurrentValueBackground(g, r, hasFocus);
|
||||
if (!comboBox.isEditable())
|
||||
paintCurrentValue(g, rectangleForCurrentValue(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the background of the currently selected item.
|
||||
*
|
||||
* @param g the g
|
||||
* @param bounds the bounds
|
||||
* @param hasFocus the has focus
|
||||
* @see javax.swing.plaf.basic.BasicComboBoxUI#paintCurrentValueBackground(java.awt.Graphics, java.awt.Rectangle, boolean)
|
||||
*/
|
||||
@Override
|
||||
public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean hasFocus) {
|
||||
ICON_9.getWithComboState("", comboBox.isEnabled(), mouseDown, mouseInside)
|
||||
.draw((Graphics2D) g, bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
//* copy from BasicComboBoxUI and modified by jb2011
|
||||
/**
|
||||
* Creates the default renderer that will be used in a non-editiable combo
|
||||
* box. A default renderer will used only if a renderer has not been
|
||||
* explicitly set with <code>setRenderer</code>.
|
||||
*
|
||||
* @return a <code>ListCellRender</code> used for the combo box
|
||||
* @see javax.swing.JComboBox#setRenderer
|
||||
*/
|
||||
@Override
|
||||
protected ListCellRenderer createRenderer() {
|
||||
return new BEComboBoxRenderer.UIResource(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 改变方法可见性
|
||||
*/
|
||||
@Override
|
||||
public Insets getInsets() {
|
||||
return super.getInsets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the popup portion of the combo box.
|
||||
*
|
||||
* 目的是修正弹出popup窗口的x、y坐标,不像菜单UI里有
|
||||
* Menu.menuPopupOffsetX等4个属性可设置以备对坐标进行调整,BeautyEye LNF中由Jack Jiang
|
||||
* 依照Menu中的实现自定义了2个属性,以便以后配置。参考自jdk1.6.0_u18源码.
|
||||
*
|
||||
* @return an instance of <code>ComboPopup</code>
|
||||
* @see javax.swing.plaf.basic.BasicComboBoxUI#createPopup()
|
||||
*/
|
||||
@Override
|
||||
protected ComboPopup createPopup() {
|
||||
return new BasicComboPopup(comboBox) {
|
||||
/**
|
||||
* popupOffsetX是jb2011自定的属性,用于修正下拉框的弹出窗的X坐标
|
||||
*/
|
||||
private final int popupOffsetX = UIManager.getInt("ComboBox.popupOffsetX");
|
||||
/**
|
||||
* popupOffsetY是jb2011自定的属性,用于修正下拉框的弹出窗的Y坐标
|
||||
*/
|
||||
private final int popupOffsetY = UIManager.getInt("ComboBox.popupOffsetY");
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
setListSelection(comboBox.getSelectedIndex());
|
||||
Point location = getPopupLocation();
|
||||
show(comboBox, //以下x、y坐标修正代码由Jack Jiang增加
|
||||
location.x + popupOffsetX, //*~ popupOffsetX是自定属性,用于修改弹出窗的X坐标
|
||||
location.y + popupOffsetY //*~ popupOffsetY是自定属性,用于修改弹出窗的Y坐标
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list selection index to the selectedIndex. This method
|
||||
* is used to synchronize the list selection with the combo box
|
||||
* selection.
|
||||
*
|
||||
* @param selectedIndex the index to set the list
|
||||
* @see javax.swing.plaf.basic.BasicComboPopup#setListSelection(int)
|
||||
*/
|
||||
private void setListSelection(int selectedIndex) {
|
||||
if (selectedIndex == -1)
|
||||
list.clearSelection();
|
||||
else {
|
||||
list.setSelectedIndex(selectedIndex);
|
||||
list.ensureIndexIsVisible(selectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the upper left location of the Popup.
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicComboPopup#getPopupLocation()
|
||||
*/
|
||||
private Point getPopupLocation() {
|
||||
Dimension popupSize = comboBox.getSize();
|
||||
Insets insets = getInsets();
|
||||
|
||||
// reduce the width of the scrollpane by the insets so that the popup
|
||||
// is the same width as the combo box.
|
||||
popupSize.setSize(popupSize.width - (insets.right + insets.left),
|
||||
getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
|
||||
Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height,
|
||||
popupSize.width, popupSize.height);
|
||||
Dimension scrollSize = popupBounds.getSize();
|
||||
Point popupLocation = popupBounds.getLocation();
|
||||
|
||||
scroller.setMaximumSize(scrollSize);
|
||||
scroller.setPreferredSize(scrollSize);
|
||||
scroller.setMinimumSize(scrollSize);
|
||||
|
||||
list.revalidate();
|
||||
|
||||
return popupLocation;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default editor that will be used in editable combo boxes. A
|
||||
* default editor will be used only if an editor has not been explicitly set
|
||||
* with <code>setEditor</code>.
|
||||
*
|
||||
* 重写父类方法的目的是使得默认的
|
||||
* Editor透明(即不填充默认背景),因为BE LNF中JTextField的LNF是用NP图
|
||||
* 实现的,此处不透明的话就会遮住NP背景图,从而使得外观难看。
|
||||
*
|
||||
* Fixed Issue 49(https://code.google.com/p/beautyeye/issues/detail?id=49)
|
||||
*
|
||||
* @return a <code>ComboBoxEditor</code> used for the combo box
|
||||
* @see javax.swing.JComboBox#setEditor
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsComboBoxUI.WindowsComboBoxEditor
|
||||
*/
|
||||
@Override
|
||||
protected ComboBoxEditor createEditor() {
|
||||
BasicComboBoxEditor.UIResource bcbe = new BasicComboBoxEditor.UIResource();
|
||||
Component c = bcbe.getEditorComponent();
|
||||
if (c != null) {
|
||||
//把默认的Editor设置成透明(editor不透明的话就会遮住NP背景图,从而使得外观难看)
|
||||
((JComponent) c).setOpaque(false);
|
||||
|
||||
//* 以下这段是为了给默认Editor加上border而加(没有它个border将使
|
||||
//* 得与不可编辑comboBox的内容组件看起来有差异哦),
|
||||
//* 在WindowsComboBoxUI中,这段代码是放在WindowsComboBoxEditor
|
||||
//* 中的方法createEditorComponent中实现,由于该 方法是1.6里才有的,
|
||||
//* BE LNF因要兼容java1.5,所以不作类似实现就在本方法中实现也没有问题。
|
||||
//* 类似实现请参考WindowsComboBoxUI.WindowsComboBoxEditor类
|
||||
// JTextField editor = (JTextField)c;
|
||||
Border border = (Border) UIManager.get("ComboBox.editorBorder");
|
||||
if (border != null)
|
||||
((JComponent) c).setBorder(border);
|
||||
}
|
||||
return bcbe;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// MouseListener Methods
|
||||
private boolean mouseInside = false;
|
||||
private boolean mouseDown = false;
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (comboBox.isEditable()) {
|
||||
if (e.getComponent() == arrowButton)
|
||||
mouseInside = true;
|
||||
} else {
|
||||
mouseInside = true;
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
if (comboBox.isEditable()) {
|
||||
if (e.getComponent() == arrowButton)
|
||||
mouseInside = false;
|
||||
} else {
|
||||
mouseInside = false;
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (comboBox.isEditable()) {
|
||||
if (e.getComponent() == arrowButton)
|
||||
mouseDown = true;
|
||||
} else {
|
||||
mouseDown = true;
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (comboBox.isEditable()) {
|
||||
if (e.getComponent() == arrowButton)
|
||||
mouseDown = false;
|
||||
} else {
|
||||
mouseDown = false;
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.combox;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
/* ~~注:这个属性是Jack Jiang仿照JTabel里的实现自已加的属性,目的是控制选择框的弹出列表的边框空白 */
|
||||
putBorder("ComboBox.scrollPaneBorder", 0, 0, 0, 0);
|
||||
|
||||
// 不能设置alpha通道小于255的透明颜色,否则会出现无法重paint的问题
|
||||
putColor("ComboBox.background", 242, 242, 242);
|
||||
put("ComboBox.disabledBackground", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
// put("ComboBox.buttonBackground", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
putColor("ComboBox.buttonBackground", 242, 242, 242);
|
||||
put("ComboBox.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("ComboBox.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("ComboBox.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
//render之外的衬距,此设置将改变下拉框的整体占位大小
|
||||
putInsets("ComboBox.padding", 0, 0, 0, 0);//5,8,5,8));
|
||||
//true表示下拉箭头按钮的宽度无条件=高度,否则宽度不与高度保持等长(使用自身长度)
|
||||
UIManager.put("ComboBox.squareButton", true);
|
||||
|
||||
//此border将决定ArrowButton的外衬大小(即框内衬空白大小),此大小决定conbox的高度和宽度,另一种方法
|
||||
//是通过设置render的border也能达到调整combox的高度和宽度,而且对lnf来说通过设置render的border是最佳方案
|
||||
putBorder("ComboBox.border", 0, 4, 0, 0);//new BERoundBorder(0).setThickness(10)));//.setArcWidth(10).setLineColor(new Color(0,0,0,0))));//使用全透明色绘边框,目的就是要让它的背景显现出来(NipePatch图实现)
|
||||
putBorder("ComboBox.editorBorder", 0, 4, 0, 0);//windows 外观下认是1,2,1,1)));
|
||||
|
||||
put("ComboBoxUI", BEComboBoxUI.class);
|
||||
/* ~~注:这个属性是Jack Jiang为了更好的ui效果和方便未来的设定自已加的属性 */
|
||||
//用于修正下拉框的弹出窗的X坐标
|
||||
put("ComboBox.popupOffsetX", 0);
|
||||
/* ~~注:这个属性是Jack Jiang为了更好的ui效果和方便未来的设定自已加的属性 */
|
||||
//用于修正下拉框的弹出窗的Y坐标
|
||||
put("ComboBox.popupOffsetY", 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEFileChooserUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.filechooser;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||
|
||||
/**
|
||||
* BeautyEye L&F implementation of a FileChooser.
|
||||
* <p>
|
||||
* 目前属通用跨平台专用UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-09-17
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BEFileChooserUI extends MetalFileChooserUI {
|
||||
|
||||
public BEFileChooserUI(JFileChooser filechooser) {
|
||||
super(filechooser);
|
||||
}
|
||||
|
||||
//
|
||||
// ComponentUI Interface Implementation methods
|
||||
//
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEFileChooserUI((JFileChooser) c);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 注:目前仅发现Windows平台的WindowsFileChooserUI存在它个问题 ! 本方法由Jack
|
||||
* Jiang实现,没有以下默认背景绘制则在BE LNF中因透明窗口而使得
|
||||
* 文件选择框内容面板的空白处出现全透明现的丑陋现象,注释掉本方法即可见之前的问题
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
g.setColor(c.getBackground());
|
||||
g.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写父类方法,以实现对文件查看列表的额外设置.
|
||||
* <p>
|
||||
* 为什么要重写此方法,没有更好的方法吗?<br>
|
||||
* 答:因父类的封装结构不佳,filePane是private私有,子类中无法直接引用,
|
||||
* 要想对filePane中的文列表额外设置,目前重写本方法是个没有办法的方法.
|
||||
* <p>
|
||||
* sun.swing.FilePane源码可查看地址:<a href="http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/swing/FilePane.java">Click
|
||||
* here.</a>
|
||||
*
|
||||
* @param fc the fc
|
||||
* @return the j panel
|
||||
*/
|
||||
@Override
|
||||
protected JPanel createList(JFileChooser fc) {
|
||||
JPanel p = super.createList(fc);
|
||||
|
||||
//* 以下代码的作用就是将文件列表JList对象引用给找回来(通过从它的父面板中层层向下搜索)
|
||||
//* ,因无法从父类中直接获得列表对象的直接引用,只能用此笨办法了
|
||||
if (p.getComponentCount() > 0) {
|
||||
Component scollPane = p.getComponent(0);
|
||||
if (scollPane != null && scollPane instanceof JScrollPane) {
|
||||
JViewport vp = ((JScrollPane) scollPane).getViewport();
|
||||
if (vp != null) {
|
||||
Component fileListView = vp.getView();
|
||||
//终于找到了文件列表的实例引用
|
||||
if (fileListView != null && fileListView instanceof JList)
|
||||
//把列表的行高改成-1(即自动计算列表每个单元的行高而不指定固定值)
|
||||
//* 说明:在BeautyEye LNF中,为了便JList的UI更好看,在没有其它方法有前
|
||||
//* 提下就在JList的BEListUI中给它设置了默写行高32,而JFildChooser中的
|
||||
//* 文件列表将会因此而使得单元行高很大——从而导致文件列表很难看,此处就是恢复
|
||||
//* 文件列表单元行高的自动计算,而非指定固定行高。
|
||||
//*
|
||||
//* 说明2:为什么不能利用list.getClientProperty("List.isFileList")从而在JList
|
||||
//* 的ui中进行判断并区别对待是否是文件列表呢?
|
||||
//* 答:因为"List.isFileList"是在BasicFileChooserUI中设置的,也就是说当为个属性被
|
||||
//* 设置的时候JFileChooser中的文件列表已经实例化完成(包括它的ui初始化),所以此时
|
||||
//* 如果在JList的ui中想区分是不可能的,因它还没有被调置,这个设置主要是供BasicListUI
|
||||
//* 在被实例化完成后,来异步处理这个属性的(通过监听属性改变事件来实现的)
|
||||
((JList) fileListView).setFixedCellHeight(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Renderer for Types ComboBox
|
||||
// //
|
||||
// protected FilterComboBoxRenderer createFilterComboBoxRenderer()
|
||||
// {
|
||||
// return new BEFilterComboBoxRenderer();
|
||||
// }
|
||||
// /**
|
||||
// * Render different type sizes and styles.
|
||||
// */
|
||||
// protected class BEFilterComboBoxRenderer extends FilterComboBoxRenderer
|
||||
// {
|
||||
// public BEFilterComboBoxRenderer()
|
||||
// {
|
||||
// super();
|
||||
//
|
||||
//// //设置成透明背景则意味着不需要背景填充,但本类中的应用场景有点特殊
|
||||
//// //——默认的render的UI里不需要绘制背景的情况下本类才可进行NinePatch图作为背景进行填充
|
||||
//// setOpaque(false);
|
||||
// //TODO 此border(render的内衬)可以作为一个UIManager的属性哦,方便以后设置
|
||||
// //注:此内衬是决定列表单元间的上下左右空白的关键哦!
|
||||
//// setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 8));
|
||||
// }
|
||||
//
|
||||
// //按理说本方法中的是否选中背景填充实现逻辑在Render的UI中实现最为合理,但由于
|
||||
// //本类就是处理于UI实现中,所以容易产生冲突,故而不适宜自定义Ui实现,干脆硬编码则更直接
|
||||
// public void paintComponent(Graphics g)
|
||||
// {
|
||||
// //** 本HACK是为了解决 Issue 30:因JFileChooser中的文件类型选择下拉框的render
|
||||
// //** (即本render)是自定义的(不是使用的ComboxUI里由BE LNF定义好的render而
|
||||
// //** 导致的视觉效果不佳的问题
|
||||
// //##### HACK:强行把绘制坐标右移、下移——以便使得与左边的空折多一点,要不然就太难看了
|
||||
// g.translate(5, 1);
|
||||
//
|
||||
// //照常绘制(只是之前的坐标被移了一下而已)
|
||||
// super.paintComponent(g);
|
||||
//
|
||||
// //##### HACK:恢复坐标
|
||||
// g.translate(-5, -1);
|
||||
// }
|
||||
// }
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.filechooser;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
/**
|
||||
* The Class __UI__.
|
||||
*/
|
||||
public class __UI__ extends UI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("tree");
|
||||
|
||||
public static void uiImpl() {
|
||||
//文件查看列表的边框实现
|
||||
put("FileChooser.listViewBorder", new org.jackhuang.hmcl.laf.scroll.ScrollPaneBorder());
|
||||
//此颜色将决定windows平台下文件选择面板的左边WindowsPlaceBar的背景色
|
||||
putColor("ToolBar.shadow", 249, 248, 243);
|
||||
put("FileChooserUI", BEFileChooserUI.class);
|
||||
|
||||
UIManager.put("FileView.directoryIcon", ICON.get("closed"));
|
||||
UIManager.put("FileView.fileIcon", ICON.get("leaf"));
|
||||
|
||||
/*
|
||||
"FileView.directoryIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getTreeFolderIcon"),
|
||||
"FileView.fileIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getTreeLeafIcon"),
|
||||
"FileView.computerIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getTreeComputerIcon"),
|
||||
"FileView.hardDriveIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getTreeHardDriveIcon"),
|
||||
"FileView.floppyDriveIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getTreeFloppyDriveIcon"),
|
||||
|
||||
// File Chooser
|
||||
"FileChooser.detailsViewIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserDetailViewIcon"),
|
||||
"FileChooser.homeFolderIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserHomeFolderIcon"),
|
||||
"FileChooser.listViewIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserListViewIcon"),
|
||||
"FileChooser.newFolderIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserNewFolderIcon"),
|
||||
"FileChooser.upFolderIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserUpFolderIcon"),
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEDesktopIconUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.internalframe;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicDesktopIconUI;
|
||||
|
||||
/**
|
||||
* 内部窗体最小化时的图标ui实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsDesktopIconUI
|
||||
*/
|
||||
public class BEDesktopIconUI extends BasicDesktopIconUI {
|
||||
|
||||
private int width;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEDesktopIconUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsDesktopIconUI#installDefaults
|
||||
*/
|
||||
@Override
|
||||
public void installDefaults() {
|
||||
super.installDefaults();
|
||||
width = UIManager.getInt("DesktopIcon.width");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
c.setOpaque(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsDesktopIconUI#uninstallUI
|
||||
*/
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
BEInternalFrameTitlePane thePane = (BEInternalFrameTitlePane) iconPane;
|
||||
super.uninstallUI(c);
|
||||
thePane.uninstallListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
iconPane = new BEInternalFrameTitlePane(frame) {
|
||||
@Override
|
||||
protected void paintTitlePaneImpl(Insets frameInsets, Graphics g,
|
||||
int width, int height, boolean isSelected) {
|
||||
//** Swing BUG补尝:重写父类的目的就是想用Insets(0,0,0,0)来调用paintTitlePaneImpl(否则因
|
||||
//** BasicInternalFrameTitlePane中的布局bug,将会导致填充错位)
|
||||
Insets instes = new Insets(0, 0, 0, 0);
|
||||
super.paintTitlePaneImpl(instes, g, width, height, isSelected);
|
||||
}
|
||||
};
|
||||
desktopIcon.setLayout(new BorderLayout());
|
||||
desktopIcon.add(iconPane, BorderLayout.CENTER);
|
||||
desktopIcon.setBorder(UIManager.getBorder("InternalFrame.border"));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see
|
||||
* com.sun.java.swing.plaf.windows.WindowsDesktopIconUI#getPreferredSize(javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
// Windows desktop icons can not be resized. Therefore, we should
|
||||
// always return the minimum size of the desktop icon. See
|
||||
// getMinimumSize(JComponent c).
|
||||
return getMinimumSize(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows desktop icons are restricted to a width of 160 pixels by default.
|
||||
* This value is retrieved by the DesktopIcon.width property.
|
||||
*
|
||||
* @param c the c
|
||||
* @return the minimum size
|
||||
* @see
|
||||
* com.sun.java.swing.plaf.windows.WindowsDesktopIconUI#getPreferredSize(javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
//## Bug FIX:see Issue 60(https://code.google.com/p/beautyeye/issues/detail?id=60&can=1)
|
||||
//## bug起源:此bug源自WindowsDesktopIconUI,BeautyEye因参考了它的实现因而也把该bug带了过来。
|
||||
//## 是否解决:已于2012-10-19日由Jack Jiang解决。
|
||||
//## bug描述:在某些情况下(比如在cpcns的定制be lnf项目中,它的内部窗口先最大化后再最小化时,该DesptopIcon
|
||||
//## 的高度就变的较小(与正常状态下有差异),具体原因待深究。
|
||||
//## 解决方法:参考MetalDesktopIconUI里的实现,用现在的代码即可解决这个问题。
|
||||
// Dimension dim = super.getMinimumSize(c);
|
||||
// dim.width = width;
|
||||
// return dim;
|
||||
return new Dimension(width,
|
||||
desktopIcon.getLayout().minimumLayoutSize(desktopIcon).height);
|
||||
}
|
||||
}
|
@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEInternalFrameTitlePane.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.internalframe;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
|
||||
import org.jackhuang.hmcl.laf.titlepane.BETitlePane;
|
||||
import org.jackhuang.hmcl.laf.utils.MySwingUtilities2;
|
||||
import org.jackhuang.hmcl.laf.utils.WinUtils;
|
||||
|
||||
/**
|
||||
* 内部窗体的标题栏UI实现.
|
||||
*
|
||||
* BeautyEye外观实现中取消了isPalette的所有特殊处理,isPalette及相关属性在
|
||||
*该外观中将失去意义,请注意!
|
||||
*虽然beautyEye是参考自MetalLookAndFeel,但因beautyEye使用了Insets很大的立体边框,
|
||||
* 则如果还要像MetalLookAndFeel实现Palette类型的JInternalFrame则效果会很难看,干脆就就像
|
||||
* WindowsLookAndFeel一样,不去理会什么Palette,在当前的L&F下没有任何减分。
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsInternalFrameTitlePane
|
||||
* @author Jack Jiang
|
||||
*/
|
||||
public class BEInternalFrameTitlePane extends BasicInternalFrameTitlePane {
|
||||
// protected boolean isPalette = false;
|
||||
// protected Icon paletteCloseIcon;
|
||||
// protected int paletteTitleHeight;
|
||||
|
||||
/**
|
||||
* The Constant handyEmptyBorder.
|
||||
*/
|
||||
private static final Border handyEmptyBorder = new EmptyBorder(0, 0, 0, 0);
|
||||
|
||||
/**
|
||||
* Key used to lookup Color from UIManager. If this is null,
|
||||
* <code>getWindowTitleBackground</code> is used.
|
||||
*/
|
||||
private String selectedBackgroundKey;
|
||||
/**
|
||||
* Key used to lookup Color from UIManager. If this is null,
|
||||
* <code>getWindowTitleForeground</code> is used.
|
||||
*/
|
||||
private String selectedForegroundKey;
|
||||
/**
|
||||
* Key used to lookup shadow color from UIManager. If this is null,
|
||||
* <code>getPrimaryControlDarkShadow</code> is used.
|
||||
*/
|
||||
private String selectedShadowKey;
|
||||
/**
|
||||
* Boolean indicating the state of the <code>JInternalFrame</code>s closable
|
||||
* property at <code>updateUI</code> time.
|
||||
*/
|
||||
private boolean wasClosable;
|
||||
|
||||
/**
|
||||
* The buttons width.
|
||||
*/
|
||||
int buttonsWidth = 0;
|
||||
|
||||
/**
|
||||
* Instantiates a new bE internal frame title pane.
|
||||
*
|
||||
* @param f the f
|
||||
*/
|
||||
public BEInternalFrameTitlePane(JInternalFrame f) {
|
||||
super(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
// This is done here instead of in installDefaults as I was worried
|
||||
// that the BasicInternalFrameUI might not be fully initialized, and
|
||||
// that if this resets the closable state the BasicInternalFrameUI
|
||||
// Listeners that get notified might be in an odd/uninitialized state.
|
||||
updateOptionPaneState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
setFont(UIManager.getFont("InternalFrame.titleFont"));
|
||||
// paletteTitleHeight = UIManager
|
||||
// .getInt("InternalFrame.paletteTitleHeight");
|
||||
// paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon");
|
||||
wasClosable = frame.isClosable();
|
||||
selectedForegroundKey = selectedBackgroundKey = null;
|
||||
if (true)
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
if (wasClosable != frame.isClosable())
|
||||
frame.setClosable(wasClosable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createButtons() {
|
||||
super.createButtons();
|
||||
|
||||
Boolean paintActive = frame.isSelected() ? Boolean.TRUE : Boolean.FALSE;
|
||||
iconButton.putClientProperty("paintActive", paintActive);
|
||||
iconButton.setBorder(handyEmptyBorder);
|
||||
|
||||
maxButton.putClientProperty("paintActive", paintActive);
|
||||
maxButton.setBorder(handyEmptyBorder);
|
||||
|
||||
closeButton.putClientProperty("paintActive", paintActive);
|
||||
closeButton.setBorder(handyEmptyBorder);
|
||||
|
||||
// The palette close icon isn't opaque while the regular close icon is.
|
||||
// This makes sure palette close buttons have the right background.
|
||||
closeButton.setBackground(MetalLookAndFeel.getPrimaryControlShadow());
|
||||
|
||||
if (true) {
|
||||
iconButton.setContentAreaFilled(false);
|
||||
maxButton.setContentAreaFilled(false);
|
||||
closeButton.setContentAreaFilled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent's method to do nothing. Metal frames do not have
|
||||
* system menus.
|
||||
*/
|
||||
@Override
|
||||
protected void assembleSystemMenu() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent's method to do nothing. Metal frames do not have
|
||||
* system menus.
|
||||
*
|
||||
* @param systemMenu the system menu
|
||||
*/
|
||||
@Override
|
||||
protected void addSystemMenuItems(JMenu systemMenu) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent's method to do nothing. Metal frames do not have
|
||||
* system menus.
|
||||
*/
|
||||
@Override
|
||||
protected void showSystemMenu() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent's method avoid creating a menu bar. Metal frames do
|
||||
* not have system menus.
|
||||
*/
|
||||
@Override
|
||||
protected void addSubComponents() {
|
||||
add(iconButton);
|
||||
add(maxButton);
|
||||
add(closeButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyChangeListener createPropertyChangeListener() {
|
||||
return new MetalPropertyChangeHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutManager createLayout() {
|
||||
return new XMetalTitlePaneLayout();
|
||||
}
|
||||
|
||||
class MetalPropertyChangeHandler extends
|
||||
BasicInternalFrameTitlePane.PropertyChangeHandler {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String prop = (String) evt.getPropertyName();
|
||||
if (prop.equals(JInternalFrame.IS_SELECTED_PROPERTY)) {
|
||||
Boolean b = (Boolean) evt.getNewValue();
|
||||
iconButton.putClientProperty("paintActive", b);
|
||||
closeButton.putClientProperty("paintActive", b);
|
||||
maxButton.putClientProperty("paintActive", b);
|
||||
} else if ("JInternalFrame.messageType".equals(prop)) {
|
||||
updateOptionPaneState();
|
||||
frame.repaint();
|
||||
}
|
||||
super.propertyChange(evt);
|
||||
}
|
||||
}
|
||||
|
||||
class XMetalTitlePaneLayout extends TitlePaneLayout {
|
||||
|
||||
@Override
|
||||
public void addLayoutComponent(String name, Component c) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLayoutComponent(Component c) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container c) {
|
||||
return minimumLayoutSize(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container c) {
|
||||
// Compute width.
|
||||
int width = 30;
|
||||
if (frame.isClosable())
|
||||
width += 21;
|
||||
if (frame.isMaximizable())
|
||||
width += 16 + (frame.isClosable() ? 10 : 4);
|
||||
if (frame.isIconifiable())
|
||||
width += 16 + (frame.isMaximizable() ? 2
|
||||
: (frame.isClosable() ? 10 : 4));
|
||||
FontMetrics fm = frame.getFontMetrics(getFont());
|
||||
String frameTitle = frame.getTitle();
|
||||
int title_w = frameTitle != null ? MySwingUtilities2.stringWidth(
|
||||
frame, fm, frameTitle) : 0;
|
||||
int title_length = frameTitle != null ? frameTitle.length() : 0;
|
||||
|
||||
if (title_length > 2) {
|
||||
int subtitle_w = MySwingUtilities2.stringWidth(frame, fm, frame
|
||||
.getTitle().substring(0, 2)
|
||||
+ "...");
|
||||
width += (title_w < subtitle_w) ? title_w : subtitle_w;
|
||||
} else
|
||||
width += title_w;
|
||||
|
||||
// Compute height.
|
||||
int height = 0;
|
||||
|
||||
// if (isPalette)
|
||||
// {
|
||||
// height = paletteTitleHeight;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
int fontHeight = fm.getHeight();
|
||||
fontHeight += 4;//默认是 +=7
|
||||
Icon icon = frame.getFrameIcon();
|
||||
int iconHeight = 0;
|
||||
if (icon != null)
|
||||
// SystemMenuBar forces the icon to be 16x16 or less.
|
||||
iconHeight = Math.min(icon.getIconHeight(), 16);
|
||||
iconHeight += 5;
|
||||
height = Math.max(fontHeight, iconHeight) + 5;//默认是 +0,modified by jb2011 2012-06-18
|
||||
}
|
||||
|
||||
return new Dimension(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container c) {
|
||||
boolean leftToRight = WinUtils.isLeftToRight(frame);
|
||||
|
||||
int w = getWidth();
|
||||
int x = leftToRight ? w : 0;
|
||||
int y = 5;//默认是0,modified by jb2011
|
||||
int spacing;
|
||||
|
||||
// assumes all buttons have the same dimensions
|
||||
// these dimensions include the borders
|
||||
int buttonHeight = closeButton.getIcon().getIconHeight();
|
||||
int buttonWidth = closeButton.getIcon().getIconWidth();
|
||||
|
||||
if (frame.isClosable()) // if (isPalette)
|
||||
// {
|
||||
// spacing = 3;
|
||||
// x += leftToRight ? -spacing - (buttonWidth + 2) : spacing;
|
||||
// closeButton.setBounds(x, y, buttonWidth + 2,
|
||||
// getHeight() - 4);
|
||||
// if (!leftToRight)
|
||||
// x += (buttonWidth + 2);
|
||||
// }
|
||||
// else
|
||||
{
|
||||
spacing = 4;
|
||||
x += leftToRight ? -spacing - buttonWidth : spacing;
|
||||
closeButton.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
if (!leftToRight)
|
||||
x += buttonWidth;
|
||||
}
|
||||
|
||||
if (frame.isMaximizable())// && !isPalette)
|
||||
{
|
||||
spacing = frame.isClosable() ? 2 : 4; //10 : 40
|
||||
x += leftToRight ? -spacing - buttonWidth : spacing;
|
||||
maxButton.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
if (!leftToRight)
|
||||
x += buttonWidth;
|
||||
}
|
||||
|
||||
if (frame.isIconifiable())// && !isPalette)
|
||||
{
|
||||
spacing = frame.isMaximizable() ? 2 : (frame.isClosable() ? 10
|
||||
: 4);
|
||||
x += leftToRight ? -spacing - buttonWidth : spacing;
|
||||
iconButton.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
if (!leftToRight)
|
||||
x += buttonWidth;
|
||||
}
|
||||
|
||||
buttonsWidth = leftToRight ? w - x : x;
|
||||
}
|
||||
}
|
||||
|
||||
// public void paintPalette(Graphics g)
|
||||
// {
|
||||
// boolean leftToRight = WinUtils.isLeftToRight(frame);
|
||||
//
|
||||
// int width = getWidth();
|
||||
// int height = getHeight();
|
||||
//
|
||||
// Color background = MetalLookAndFeel.getPrimaryControlShadow();
|
||||
// Color darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
|
||||
//
|
||||
// NLTitlePane.paintTitlePane(g, 0, 0, width , height, false
|
||||
// , background, darkShadow);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
// if (isPalette)
|
||||
// {
|
||||
// paintPalette(g);
|
||||
// return;
|
||||
// }
|
||||
|
||||
boolean leftToRight = WinUtils.isLeftToRight(frame);
|
||||
boolean isSelected = frame.isSelected();//! 选中与否的判断方式,参见border部分的注释
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
Color background = null;
|
||||
Color foreground = null;
|
||||
Color shadow = null;
|
||||
|
||||
if (isSelected) {
|
||||
// if (!true)
|
||||
// {
|
||||
// closeButton.setContentAreaFilled(true);
|
||||
// maxButton.setContentAreaFilled(true);
|
||||
// iconButton.setContentAreaFilled(true);
|
||||
// }
|
||||
if (selectedBackgroundKey != null)
|
||||
background = UIManager.getColor(selectedBackgroundKey);
|
||||
if (background == null)
|
||||
background = UIManager.getColor("activeCaption");
|
||||
if (selectedForegroundKey != null)
|
||||
foreground = UIManager.getColor(selectedForegroundKey);
|
||||
if (selectedShadowKey != null)
|
||||
shadow = UIManager.getColor(selectedShadowKey);
|
||||
if (shadow == null)
|
||||
shadow = UIManager.getColor("activeCaptionBorder");
|
||||
if (foreground == null)
|
||||
foreground = UIManager.getColor("activeCaptionText");
|
||||
} else {
|
||||
if (!true) {
|
||||
closeButton.setContentAreaFilled(false);
|
||||
maxButton.setContentAreaFilled(false);
|
||||
iconButton.setContentAreaFilled(false);
|
||||
}
|
||||
background = UIManager.getColor("inactiveCaption");
|
||||
foreground = UIManager.getColor("inactiveCaptionText");
|
||||
shadow = UIManager.getColor("inactiveCaptionBorder");
|
||||
}
|
||||
|
||||
//---------------------------------------------------绘制标题栏背景
|
||||
// Color topDarkShadow2 = LNFUtils.getColor(
|
||||
// background, -40, -40, -40)
|
||||
// ,topHightLight2 = LNFUtils.getColor(background,
|
||||
// 60, 60, 60)
|
||||
// ,topDarkHightLight2 = LNFUtils.getColor(background,
|
||||
// 20, 20, 20);
|
||||
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 绘制标题栏背景START */
|
||||
/*
|
||||
* ** bug修正 by js,2009-09-30(这因是JDK1.5的Swing底层BUG)
|
||||
*
|
||||
* BUG描述:当操作系统的主题切换时,JInternalFrame有时相同的方法this.getBounds()获得的结果是不一样的
|
||||
* ,这种差异主要在于有时this.getBounds()获得的结果并未包括它的border,主要表现就是结果
|
||||
* 的(x,y)的坐标是未包含border的坐标,因而这种情况下它的(x=0,y=0),而正确应该
|
||||
* (x=border.insets.left,y=border.insets.top),如果无视此bug,则titlePane
|
||||
* 在填充时会变的丑陋。
|
||||
*
|
||||
* 解决方法:当确知这个bug发生后,只能以人工方式弥补这种异相,如 强制修正其(x,y)的坐标,并相应地调整
|
||||
* titlePane的填充区域。
|
||||
*/
|
||||
// Border b=frame.getBorder();
|
||||
// Insets is=b.getBorderInsets(frame);
|
||||
// Rectangle bounds = this.getBounds();
|
||||
// int paintTitlePaneX = bounds.x,paintTitlePaneY = bounds.y;
|
||||
//// boolean isBUG = false;
|
||||
////// System.out.println("JInternalFrame的UI是否处于正常isBUG="+isBUG);
|
||||
//// if(isBUG=(is.left!=bounds.x))//当is.left!=bounds.x即可认定已经产生了BUG
|
||||
//// paintTitlePaneX = is.left;
|
||||
//// if(isBUG=(is.top!=bounds.y))//当is.left!=bounds.x同样可认定已经产生了BUG
|
||||
//// paintTitlePaneY = is.top;
|
||||
//// if(isBUG)//有BUG时的填充
|
||||
//// {
|
||||
//// //----------------------------- 以下代码是为了弥补因BUG而产生的填充异常
|
||||
//// //*以下(1),(2),(3)部分代码是用于弥补BUG下的border外观被titlePane覆盖的错误
|
||||
//// //*请参见JInternalFrameDialogBorder的边框填充代码(尽量在此处模拟出边框的TOP部分效果)>
|
||||
//// //水平第一条线(1)
|
||||
//// g.setColor(topDarkShadow2);
|
||||
//// g.drawLine(0, 0, width, 0);
|
||||
//// g.drawLine(0, 1, 0, height);//左坚线
|
||||
//// g.drawLine(width, 1, width, height);//右坚线
|
||||
//// //水平第二条线(2)
|
||||
//// g.setColor(topHightLight2);
|
||||
//// g.drawLine(1, 1, width-NLMetalBorders.InternalFrameDialogBorder.insets.left, 1);
|
||||
//// //水平第三条线(3)
|
||||
//// g.setColor(topDarkHightLight2);
|
||||
//// g.drawLine(2, 2, width-NLMetalBorders.InternalFrameDialogBorder.insets.left, 2);
|
||||
////
|
||||
//// NLTitlePane.paintTitlePane(g//左右空起的部分由Border绘制
|
||||
//// , paintTitlePaneX//ZCMetalBorders.InternalFrameDialogBorder.insets.left
|
||||
//// , paintTitlePaneY//ZCMetalBorders.InternalFrameDialogBorder.insets.left
|
||||
//// , width-is.left*2 //注意此处也因BUG而作了填充区域的调整
|
||||
//// , height, isSelected
|
||||
//// , background, shadow);
|
||||
//// //----------------------------- END
|
||||
//// }
|
||||
//// //正常无BUG时的填充
|
||||
//// else
|
||||
{
|
||||
Insets frameInsets = frame.getInsets();
|
||||
//** Swing BUG:按理说,此处是不需要传入frameInstes的,因父类BasicInternalFrameTitlePane的布局
|
||||
//是存在BUG(布计算时没有把BorderInstes算入到x、y的偏移中,导致UI中paint时只能自行
|
||||
//进行增益,否则填充的图璩形肯定就因没有算上borderInstes而错位,详见父类中的
|
||||
//BasicInternalFrameTitlePane中内部类Handler的layoutContainer方法里
|
||||
//getNorthPane().setBounds(..)这一段
|
||||
// NLTitlePane.paintTitlePane(g
|
||||
// , frameInsets.left//0
|
||||
// , frameInsets.top//0
|
||||
// , width-frameInsets.left-frameInsets.right//-0
|
||||
// , height, isSelected
|
||||
//// , background, shadow
|
||||
// );
|
||||
paintTitlePaneImpl(frameInsets, g, width, height, isSelected);
|
||||
}
|
||||
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 绘制标题栏背景END */
|
||||
|
||||
//----------------------------------------------------绘制标题及图标
|
||||
int titleLength = 0;
|
||||
int xOffset = leftToRight ? 5 : width - 5;
|
||||
String frameTitle = frame.getTitle();
|
||||
|
||||
Icon icon = frame.getFrameIcon();
|
||||
if (icon != null) {
|
||||
if (!leftToRight)
|
||||
xOffset -= icon.getIconWidth();
|
||||
int iconY = ((height / 2) - (icon.getIconHeight() / 2));
|
||||
icon.paintIcon(frame, g, xOffset + 2, iconY + 1);//默认是xOffset +0, iconY+0
|
||||
xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
|
||||
}
|
||||
|
||||
if (frameTitle != null) {
|
||||
Font f = getFont();
|
||||
g.setFont(f);
|
||||
FontMetrics fm = MySwingUtilities2.getFontMetrics(frame, g, f);
|
||||
int fHeight = fm.getHeight();
|
||||
|
||||
int yOffset = ((height - fm.getHeight()) / 2) + fm.getAscent();
|
||||
|
||||
Rectangle rect = new Rectangle(0, 0, 0, 0);
|
||||
if (frame.isIconifiable())
|
||||
rect = iconButton.getBounds();
|
||||
else if (frame.isMaximizable())
|
||||
rect = maxButton.getBounds();
|
||||
else if (frame.isClosable())
|
||||
rect = closeButton.getBounds();
|
||||
int titleW;
|
||||
|
||||
if (leftToRight) {
|
||||
if (rect.x == 0)
|
||||
rect.x = frame.getWidth() - frame.getInsets().right - 2;
|
||||
titleW = rect.x - xOffset - 4;
|
||||
frameTitle = getTitle(frameTitle, fm, titleW);
|
||||
} else {
|
||||
titleW = xOffset - rect.x - rect.width - 4;
|
||||
frameTitle = getTitle(frameTitle, fm, titleW);
|
||||
xOffset -= MySwingUtilities2.stringWidth(frame, fm, frameTitle);
|
||||
}
|
||||
|
||||
titleLength = MySwingUtilities2.stringWidth(frame, fm, frameTitle);
|
||||
|
||||
// g.setColor(Color.DARK_GRAY);//
|
||||
// NLUtils.drawString(frame, g, frameTitle, xOffset+1, yOffset+1);
|
||||
g.setColor(foreground);
|
||||
// if(NLLookAndFeel.windowTitleAntialising)
|
||||
// NLLookAndFeel.setAntiAliasing((Graphics2D) g,true);
|
||||
MySwingUtilities2.drawString(frame, g, frameTitle, xOffset, yOffset);
|
||||
// if(NLLookAndFeel.windowTitleAntialising)
|
||||
// NLLookAndFeel.setAntiAliasing((Graphics2D) g,false);
|
||||
xOffset += leftToRight ? titleLength + 5 : -5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint title pane impl.
|
||||
*
|
||||
* @param frameInsets the frame insets
|
||||
* @param g the g
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
* @param isSelected the is selected
|
||||
*/
|
||||
protected void paintTitlePaneImpl(Insets frameInsets, Graphics g,
|
||||
int width, int height, boolean isSelected) {
|
||||
BETitlePane.paintTitlePane(g,
|
||||
frameInsets.left//0
|
||||
,
|
||||
frameInsets.top//0
|
||||
,
|
||||
width - frameInsets.left - frameInsets.right//-0
|
||||
,
|
||||
height, isSelected
|
||||
// , background, shadow
|
||||
);
|
||||
}
|
||||
|
||||
// public void setPalette(boolean b)
|
||||
// {
|
||||
// isPalette = b;
|
||||
//
|
||||
// if (isPalette)
|
||||
// {
|
||||
// closeButton.setIcon(paletteCloseIcon);
|
||||
// if (frame.isMaximizable())
|
||||
// remove(maxButton);
|
||||
// if (frame.isIconifiable())
|
||||
// remove(iconButton);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// closeButton.setIcon(closeIcon);
|
||||
// if (frame.isMaximizable())
|
||||
// add(maxButton);
|
||||
// if (frame.isIconifiable())
|
||||
// add(iconButton);
|
||||
// }
|
||||
// revalidate();
|
||||
// repaint();
|
||||
// }
|
||||
/**
|
||||
* Updates any state dependant upon the JInternalFrame being shown in a
|
||||
* <code>JOptionPane</code>.
|
||||
*/
|
||||
private void updateOptionPaneState() {
|
||||
int type = -2;
|
||||
boolean closable = wasClosable;
|
||||
Object obj = frame.getClientProperty("JInternalFrame.messageType");
|
||||
|
||||
if (obj == null)
|
||||
// Don't change the closable state unless in an JOptionPane.
|
||||
return;
|
||||
if (obj instanceof Integer)
|
||||
type = ((Integer) obj).intValue();
|
||||
switch (type) {
|
||||
case JOptionPane.ERROR_MESSAGE:
|
||||
selectedBackgroundKey = "OptionPane.errorDialog.titlePane.background";
|
||||
selectedForegroundKey = "OptionPane.errorDialog.titlePane.foreground";
|
||||
selectedShadowKey = "OptionPane.errorDialog.titlePane.shadow";
|
||||
closable = false;
|
||||
break;
|
||||
case JOptionPane.QUESTION_MESSAGE:
|
||||
selectedBackgroundKey = "OptionPane.questionDialog.titlePane.background";
|
||||
selectedForegroundKey = "OptionPane.questionDialog.titlePane.foreground";
|
||||
selectedShadowKey = "OptionPane.questionDialog.titlePane.shadow";
|
||||
closable = false;
|
||||
break;
|
||||
case JOptionPane.WARNING_MESSAGE:
|
||||
selectedBackgroundKey = "OptionPane.warningDialog.titlePane.background";
|
||||
selectedForegroundKey = "OptionPane.warningDialog.titlePane.foreground";
|
||||
selectedShadowKey = "OptionPane.warningDialog.titlePane.shadow";
|
||||
closable = false;
|
||||
break;
|
||||
case JOptionPane.INFORMATION_MESSAGE:
|
||||
case JOptionPane.PLAIN_MESSAGE:
|
||||
selectedBackgroundKey = selectedForegroundKey = selectedShadowKey = null;
|
||||
closable = false;
|
||||
break;
|
||||
default:
|
||||
selectedBackgroundKey = selectedForegroundKey = selectedShadowKey = null;
|
||||
break;
|
||||
}
|
||||
if (closable != frame.isClosable())
|
||||
frame.setClosable(closable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 改变父类的方法的可见性为public,方便外界调用,仅此而已.
|
||||
*/
|
||||
@Override
|
||||
public void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEInternalFrameUI.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.internalframe;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
|
||||
/**
|
||||
* 内部窗体UI实现类.
|
||||
*
|
||||
* BeautyEye外观实现中取消了isPalette的所有特殊处理,isPalette及相关属性在
|
||||
* 该外观中将失去意义,请注意。
|
||||
*
|
||||
* @author Jack Jiang
|
||||
*/
|
||||
public class BEInternalFrameUI extends BasicInternalFrameUI {
|
||||
|
||||
/**
|
||||
* The title pane.
|
||||
*/
|
||||
private BEInternalFrameTitlePane titlePane;
|
||||
|
||||
/**
|
||||
* The Constant metalPropertyChangeListener.
|
||||
*/
|
||||
private static final PropertyChangeListener metalPropertyChangeListener = new XZCMetalPropertyChangeHandler();
|
||||
|
||||
/**
|
||||
* The Constant handyEmptyBorder.
|
||||
*/
|
||||
private static final Border handyEmptyBorder = new EmptyBorder(0, 0, 0, 0);
|
||||
|
||||
// protected static String IS_PALETTE = "JInternalFrame.isPalette";
|
||||
/**
|
||||
* The FRAM e_ type.
|
||||
*/
|
||||
private static String FRAME_TYPE = "JInternalFrame.frameType";
|
||||
|
||||
/**
|
||||
* The NORMA l_ frame.
|
||||
*/
|
||||
private static String NORMAL_FRAME = "normal";
|
||||
// private static String PALETTE_FRAME = "palette";
|
||||
/**
|
||||
* The OPTIO n_ dialog.
|
||||
*/
|
||||
private static String OPTION_DIALOG = "optionDialog";
|
||||
|
||||
/**
|
||||
* Instantiates a new bE internal frame ui.
|
||||
*
|
||||
* @param b the b
|
||||
*/
|
||||
public BEInternalFrameUI(JInternalFrame b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEInternalFrameUI((JInternalFrame) c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
|
||||
// Object paletteProp = c.getClientProperty(IS_PALETTE);
|
||||
// if (paletteProp != null)
|
||||
// {
|
||||
// setPalette(((Boolean) paletteProp).booleanValue());
|
||||
// }
|
||||
Container content = frame.getContentPane();
|
||||
stripContentBorder(content);
|
||||
//c.setOpaque(false);
|
||||
|
||||
frame.setOpaque(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
frame = (JInternalFrame) c;
|
||||
|
||||
Container cont = ((JInternalFrame) (c)).getContentPane();
|
||||
if (cont instanceof JComponent) {
|
||||
JComponent content = (JComponent) cont;
|
||||
if (content.getBorder() == handyEmptyBorder)
|
||||
content.setBorder(null);
|
||||
}
|
||||
super.uninstallUI(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners() {
|
||||
super.installListeners();
|
||||
frame.addPropertyChangeListener(metalPropertyChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners() {
|
||||
frame.removePropertyChangeListener(metalPropertyChangeListener);
|
||||
super.uninstallListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installKeyboardActions() {
|
||||
super.installKeyboardActions();
|
||||
ActionMap map = SwingUtilities.getUIActionMap(frame);
|
||||
if (map != null)
|
||||
// BasicInternalFrameUI creates an action with the same name, we override
|
||||
// it as Metal frames do not have system menus.
|
||||
map.remove("showSystemMenu");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallKeyboardActions() {
|
||||
super.uninstallKeyboardActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallComponents() {
|
||||
titlePane = null;
|
||||
super.uninstallComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip content border.
|
||||
*
|
||||
* @param c the c
|
||||
*/
|
||||
private void stripContentBorder(Object c) {
|
||||
if (c instanceof JComponent) {
|
||||
JComponent contentComp = (JComponent) c;
|
||||
Border contentBorder = contentComp.getBorder();
|
||||
if (contentBorder == null || contentBorder instanceof UIResource)
|
||||
contentComp.setBorder(handyEmptyBorder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createNorthPane(JInternalFrame w) {
|
||||
titlePane = new BEInternalFrameTitlePane(w);
|
||||
return titlePane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame type.
|
||||
*
|
||||
* @param frameType the new frame type
|
||||
*/
|
||||
private void setFrameType(String frameType) {
|
||||
if (frameType.equals(OPTION_DIALOG))
|
||||
LookAndFeel.installBorder(frame, "InternalFrame.optionDialogBorder"); // titlePane.setPalette(false);
|
||||
// else if (frameType.equals(PALETTE_FRAME))
|
||||
// {
|
||||
// LookAndFeel.installBorder(frame, "InternalFrame.paletteBorder");
|
||||
//// titlePane.setPalette(true);
|
||||
// }
|
||||
else
|
||||
LookAndFeel.installBorder(frame, "InternalFrame.border"); // titlePane.setPalette(false);
|
||||
}
|
||||
|
||||
// // this should be deprecated - jcs
|
||||
// public void setPalette(boolean isPalette)
|
||||
// {
|
||||
//// if (isPalette)
|
||||
//// {
|
||||
//// LookAndFeel.installBorder(frame, "InternalFrame.paletteBorder");
|
||||
//// }
|
||||
//// else
|
||||
// {
|
||||
// LookAndFeel.installBorder(frame, "InternalFrame.border");
|
||||
// }
|
||||
//// titlePane.setPalette(isPalette);
|
||||
// }
|
||||
private static class XZCMetalPropertyChangeHandler implements
|
||||
PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
String name = e.getPropertyName();
|
||||
JInternalFrame jif = (JInternalFrame) e.getSource();
|
||||
|
||||
if (!(jif.getUI() instanceof BEInternalFrameUI))
|
||||
return;
|
||||
|
||||
BEInternalFrameUI ui = (BEInternalFrameUI) jif.getUI();
|
||||
if (name.equals(FRAME_TYPE)) {
|
||||
if (e.getNewValue() instanceof String)
|
||||
ui.setFrameType((String) e.getNewValue());
|
||||
} // else if (name.equals(IS_PALETTE))
|
||||
// {
|
||||
// if (e.getNewValue() != null)
|
||||
// {
|
||||
// ui.setPalette(((Boolean) e.getNewValue()).booleanValue());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ui.setPalette(false);
|
||||
// }
|
||||
// }
|
||||
else if (name.equals(JInternalFrame.CONTENT_PANE_PROPERTY))
|
||||
ui.stripContentBorder(e.getNewValue());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.internalframe;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
import org.jackhuang.hmcl.laf.widget.border.BEShadowBorder;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("internal_frame");
|
||||
|
||||
public static void uiImpl() {
|
||||
//内部窗体的边框颜色(BueaytyEye中无意义,原因是BeautyEye LNF中的border是使用NP图实现)
|
||||
put("InternalFrame.borderColor", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("InternalFrame.minimizeIconBackground", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
// UIManager.put("InternalFrame.paletteCloseIcon", ICON.get("close")); //本属性在beautyEye中不会起效的
|
||||
UIManager.put("InternalFrame.icon", ICON.get("icon"));
|
||||
UIManager.put("InternalFrame.iconifyIcon", ICON.get("iconify"));
|
||||
UIManager.put("InternalFrame.minimizeIcon", ICON.get("min"));
|
||||
UIManager.put("InternalFrame.maximizeIcon", ICON.get("max"));
|
||||
UIManager.put("InternalFrame.closeIcon", ICON.get("close"));
|
||||
put("InternalFrameUI", BEInternalFrameUI.class);
|
||||
// put("InternalFrame.paletteTitleHeight", 40); //本属性在beautyEye中不会起效的
|
||||
// put("InternalFrame.titlePaneHeight", 38); //default is 25
|
||||
// put("InternalFrame.borderWidth", 10);
|
||||
Object internalFrameBorder = new BorderUIResource(new BEShadowBorder());
|
||||
UIManager.put("InternalFrame.border", internalFrameBorder);
|
||||
UIManager.put("InternalFrame.paletteBorder", internalFrameBorder);
|
||||
UIManager.put("InternalFrame.optionDialogBorder", internalFrameBorder);
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JDesktopPane相关ui属性设定
|
||||
//JDesktopPane的背景色
|
||||
put("Desktop.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
//此属性暂无意义
|
||||
// putInsetc("Desktop.minOnScreenInsets", 10, 10, 10, 10);//default is 3,3,3,3
|
||||
//JDesktopPane中内部窗体最小化时的窗体组件宽度
|
||||
put("DesktopIcon.width", 180); //默认是160
|
||||
//BeautyEye LNF中内部窗体标题栏实现
|
||||
put("DesktopIconUI", BEDesktopIconUI.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEListUI.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.list;
|
||||
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicListUI;
|
||||
|
||||
/**
|
||||
* JList的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BEListUI extends BasicListUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEListUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize JList properties, e.g. font, foreground, and background, and
|
||||
* add the CellRendererPane. The font, foreground, and background properties
|
||||
* are only set if their current value is either null or a UIResource, other
|
||||
* properties are set if the current value is null.
|
||||
*
|
||||
* @see #uninstallDefaults
|
||||
* @see #installUI
|
||||
* @see CellRendererPane
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
|
||||
//2012-08-30*******************************************************【重要说明】 START 对应BEComboBoxUI中的【重要说明】
|
||||
//* 【重要说明】因BEListUI中为了使列表行单元高变的更高(在MyDefaultListCellRenderer.java中
|
||||
//* 像COmboxRender一样通过增到border不起效果,它可能是BasicListUI的设计缺陷,它要么取FixedCellHeight
|
||||
//* 固定值,要么取getPreferSize()即自动计算高度——它似乎是不计入border的,所以render设置border不起效)
|
||||
//* 所以只能为列表单元设置因定值:list.setFixedCellHeight(30),但它将影响Combox里的行高(也会变成30高)
|
||||
//* 所以BEComboBoxUI中要把本列表UI中强制设定的30高针对Combox还原成自动计算(API中规定FixedCellHeight==-1即表示自动计算)
|
||||
//*************************************************************** 【重要说明】 END
|
||||
//* 则jb2011加入,表示列表单元固定高度,默认值=-1(即意味着行高自动计算)
|
||||
//* 使用BE LNF的项目,如要恢复行高算动计算则显示设置列表的固定行高为-1即可!
|
||||
list.setFixedCellHeight(27);//32//30);// TODO 此设置值作一个UIManager属性就可以方便以后设置了,-1是原系统默认值哦(即自动计算单元高)
|
||||
|
||||
//* 不需要了,它样强制要求它为透明可能会影响以后用户的定制需求,干脆
|
||||
//* 设置它的背景为认白色,也能达到想到的N9白色背景
|
||||
// //此设置将取消列表背景的绘制(以便BE LNF中绘制N9背景图哦)
|
||||
// list.setOpaque(false);
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* MyDefaultListCellRenderer.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.list;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JList;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* 列表单元的默认renderer实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-08-30
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MyDefaultListCellRenderer extends DefaultListCellRenderer {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("list");
|
||||
|
||||
/**
|
||||
* The is selected.
|
||||
*/
|
||||
protected boolean isSelected = false;
|
||||
|
||||
/**
|
||||
* The is focuesed.
|
||||
*/
|
||||
protected boolean isFocuesed = false;
|
||||
|
||||
/**
|
||||
* Instantiates a new my default list cell renderer.
|
||||
*/
|
||||
public MyDefaultListCellRenderer() {
|
||||
//设置成透明背景则意味着不需要背景填充,但本类中的应用场景有点特殊
|
||||
//——默认的render的UI里不需要绘制背景的情况下本类才可进行NinePatch图作为背景进行填充
|
||||
setOpaque(false);
|
||||
|
||||
//** 要像Combox的render一样设置border没用,因为列表单元不获得焦点时的border由UIManager属性List.cellNoFocusBorder决定
|
||||
// //注:此内衬是决定列表单元间的上下左右空白的关键哦!
|
||||
// setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
if (isSelected)
|
||||
//注意:2012-09-03日用的该图片右边有一个像素的空白哦,其实它是可以通过List.border的UI属性来调整的
|
||||
//之所以没有用它调整就是为了日后可以使用N9图来自由调整而无需调整代码(List.border的代码没置)
|
||||
ICON_9.get("selected_icon_bg")
|
||||
.draw((Graphics2D) g, 0, 0, this.getWidth(), this.getHeight());
|
||||
else {
|
||||
// g.setColor(this.getBackground());
|
||||
// //本Insets取this.getInsets()是符合Sun的设计初衷的,但是不合理(本身isPopupVisible==false
|
||||
// //时的背景就是特殊情况,不能与下拉项同等视之),所以此处用自定义的Insets来处理则在UI展现上更为合理 。
|
||||
// //TODO 这个Instes可以作为UI属性“ComboBox.popupNoVisibleBgInstes”方便以后设置,暂时先硬编码吧,以后再说
|
||||
// Insets is = new Insets(2,3,2,3);//this.getInsets();
|
||||
//// g.fillRect(is.left, is.top
|
||||
//// , this.getWidth()-is.left-is.right
|
||||
//// , this.getHeight()-is.top-is.bottom);
|
||||
// BEUtils.fillTextureRoundRec((Graphics2D)g, this.getBackground(), is.left, is.top
|
||||
// , this.getWidth()-is.left-is.right
|
||||
// , this.getHeight()-is.top-is.bottom,20,0);//20,20
|
||||
}
|
||||
// else
|
||||
//注意:本组件已经被设置成opaque=false即透明,否则本方法还会填充默认背景,那么选中时的
|
||||
//N9图背景因先绘将会被覆盖哦。所以要使用N9图作为选中时的背景则前提是本组件必须是透明
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
Component c = super.getListCellRendererComponent(list,
|
||||
value, index, isSelected, cellHasFocus);
|
||||
|
||||
this.isSelected = isSelected;
|
||||
this.isFocuesed = cellHasFocus;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass of DefaultListCellRenderer that implements UIResource.
|
||||
* DefaultListCellRenderer doesn't implement UIResource directly so that
|
||||
* applications can safely override the cellRenderer property with
|
||||
* DefaultListCellRenderer subclasses.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with future Swing
|
||||
* releases. The current serialization support is appropriate for short term
|
||||
* storage or RMI between applications running the same version of Swing. As
|
||||
* of 1.4, support for long term storage of all
|
||||
* JavaBeans<sup><font size="-2">TM</font></sup>
|
||||
* has been added to the <code>java.beans</code> package. Please see
|
||||
* {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
public static class UIResource extends MyDefaultListCellRenderer
|
||||
implements javax.swing.plaf.UIResource {
|
||||
}
|
||||
}
|
79
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/list/__UI__.java
Normal file
79
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/list/__UI__.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.list;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
//通过此border可以调整整个列表的上下左右的空白
|
||||
putBorder("List.border", 0, 0, 0, 0);
|
||||
//本属性将决定已被选中的列表单元显示文本的上下左右空白哦
|
||||
putBorder("List.focusCellHighlightBorder", 1, 8, 5, 3);
|
||||
/* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性 */
|
||||
putColor("List.focusSelectedCellHighlightBorderColor", 252, 87, 84); //Color.red
|
||||
/* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性,目的是使List.focusSelectedCellHighlightBorderColor有点立体效果哦 */
|
||||
putColor("List.focusSelectedCellHighlightBorderHighlightColor", 255, 255, 255, 70);//注意:这个颜色是半透明的哦
|
||||
//列表单元获得焦点时的边框(windows主题下是一个距形虚线框)——之前老也想不通的与左边隔一个像素的白边问题就是没设置它造成的
|
||||
put("List.focusSelectedCellHighlightBorder", new FocusSelectedCellHighlightBorder());
|
||||
//将决定正状态下的列表单元显示文本的上下左右空白哦
|
||||
putBorder("List.cellNoFocusBorder", 1, 8, 5, 3);
|
||||
|
||||
put("List.background", Color.white);
|
||||
put("List.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("List.selectionForeground", Color.white);//fgColor);
|
||||
put("List.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
|
||||
UIManager.put("List.cellRenderer", new MyDefaultListCellRenderer.UIResource());
|
||||
put("ListUI", BEListUI.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本border由Jack Jiang实现,它是列表单元获得焦点时的边框(windows外观
|
||||
* 下是一个距形虚线框),本border当前的样式是在在最左边画的一条红色竖线
|
||||
*/
|
||||
static class FocusSelectedCellHighlightBorder extends AbstractBorder {
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
//Insets跟List.focusCellHighlightBorder 一样即可,这样就能在视觉上保持一致罗(不一样则会有移位的难看效果)!
|
||||
return UIManager.getBorder("List.focusCellHighlightBorder").getBorderInsets(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
return getBorderInsets(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
//在左边划一条2像素宽的竖线
|
||||
g.setColor(UIManager.getColor("List.focusSelectedCellHighlightBorderColor"));
|
||||
g.fillRect(x, y + 0, 2, height - 1);//-2);//上下各空白一个像素,目的是为了与render的N9图片背景配合形成更好的视觉效果
|
||||
|
||||
//再在上面的竖线右边划一条1像素宽的亮色竖线,以便为上面的2像素竖线营造立体效果
|
||||
/* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性,目的是使List.focusSelectedCellHighlightBorder有点立体效果哦 */
|
||||
g.setColor(UIManager.getColor("List.focusSelectedCellHighlightBorderHighlightColor"));
|
||||
g.fillRect(x + 2, y + 0, 1, height - 1);//-2);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BECheckBoxMenuItemUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
|
||||
/**
|
||||
* JCheckBoxMenuItem的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BECheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("menu_check");
|
||||
|
||||
/**
|
||||
* 是否强制单项透明(当强制不透明时,在普通状态下该item将不会被绘制背景).
|
||||
*/
|
||||
private static boolean enforceTransparent = true;
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new BECheckBoxMenuItemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground(Graphics g, JMenuItem menuItem,
|
||||
Color bgColor) {
|
||||
// if (WindowsMenuItemUI.isVistaPainting()) {
|
||||
// WindowsMenuItemUI.paintBackground(accessor, g, menuItem, bgColor);
|
||||
// return;
|
||||
// }
|
||||
// super.paintBackground(g, menuItem, bgColor);
|
||||
// see parent!
|
||||
ButtonModel model = menuItem.getModel();
|
||||
Color oldColor = g.getColor();
|
||||
int menuWidth = menuItem.getWidth();
|
||||
int menuHeight = menuItem.getHeight();
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
if (model.isArmed()
|
||||
|| (menuItem instanceof JMenu && model.isSelected())) {
|
||||
g.setColor(bgColor);
|
||||
|
||||
BEMenuUI.drawSelectedBackground(g, 0, 0, menuWidth, menuHeight);
|
||||
|
||||
// /****** 选中的背景样式现在是渐变加圆角填充了,impled by js */
|
||||
// NLLookAndFeel.setAntiAliasing(g2, true);
|
||||
// //矩形填充
|
||||
// Paint oldpaint = g2.getPaint();
|
||||
// GradientPaint gp = new GradientPaint(0, 0
|
||||
// ,GraphicHandler.getColor(bgColor, 35, 35, 35)
|
||||
// ,0, menuHeight,bgColor
|
||||
// );
|
||||
// g2.setPaint(gp);
|
||||
// g.fillRoundRect(0, 0, menuWidth, menuHeight,5,5);
|
||||
// g2.setPaint(oldpaint);
|
||||
// NLLookAndFeel.setAntiAliasing(g2, false);
|
||||
} else if (!enforceTransparent) {
|
||||
g.setColor(menuItem.getBackground());
|
||||
g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
}
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see
|
||||
* com.sun.java.swing.plaf.windows.WindowsIconFactory.CheckBoxMenuItemIcon
|
||||
*/
|
||||
public static class CheckBoxMenuItemIcon implements Icon, UIResource, Serializable {
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
g.drawImage(ICON.get(((AbstractButton) c).getModel().isSelected() ? "checked" : "normal").getImage(),
|
||||
x - 4, y - 3, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return 16;
|
||||
}// default 9
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return 16;
|
||||
}// default 9
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEMenuBarUI.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuBarUI;
|
||||
|
||||
/**
|
||||
* JMenuBar的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuBarUI
|
||||
*/
|
||||
public class BEMenuBarUI extends BasicMenuBarUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new BEMenuBarUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
int width = c.getWidth();
|
||||
int height = c.getHeight();
|
||||
|
||||
//背景划一个灰色底线(方便与JMenuBar的顶层菜单项的底色融合)
|
||||
g.setColor(BEMenuUI.MENU_UNSELECTED_UNDERLINE_COLOR);
|
||||
g.fillRect(0, height - BEMenuUI.DECORATED_UNDERLINE_HEIGHT, width, height);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEMenuItemUI.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||
|
||||
/**
|
||||
* JMenuItem的UI实现类.
|
||||
*
|
||||
* 特别注意:BasicMenuItemUI中针对Vista及后来的Windows版本预设了很多其它LNF不需要的属性,
|
||||
* 预设的属性详见BasicMenuItemUI及WindowsLookAndFeel中的initVistaComponentDefaults(..)方法.
|
||||
* 这些属性只能会在vista及更新的windows平台上过运行时才会起效,所以除此之外的windows测不出来,
|
||||
* 容易出现ui视觉差异.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BEMenuItemUI extends BasicMenuItemUI {
|
||||
|
||||
/**
|
||||
* 是否强制单项透明(当强制不透明时,在普通状态下该item将不会被绘制背景).
|
||||
*/
|
||||
private static boolean enforceTransparent = true;// TODO 可以提炼成UI属性
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEMenuItemUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuItemUI#paintBackground(java.awt.Graphics, javax.swing.JMenuItem, java.awt.Color)
|
||||
* @see javax.swing.plaf.basic.BasicMenuItemUI#paintBackground(java.awt.Graphics, javax.swing.JMenuItem, java.awt.Color)
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
|
||||
ButtonModel model = menuItem.getModel();
|
||||
Color oldColor = g.getColor();
|
||||
int menuWidth = menuItem.getWidth();
|
||||
int menuHeight = menuItem.getHeight();
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
if (model.isArmed()
|
||||
|| (menuItem instanceof JMenu && model.isSelected()))
|
||||
//菜单项的样式绘制(用NinePatch图来填充)
|
||||
BEMenuUI.drawSelectedBackground(g, 0, 0, menuWidth, menuHeight);
|
||||
else if (!enforceTransparent) {
|
||||
g.setColor(menuItem.getBackground());
|
||||
g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
}
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
}
|
306
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/menu/BEMenuUI.java
Normal file
306
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/menu/BEMenuUI.java
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEMenuUI.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicMenuUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.utils.WinUtils;
|
||||
|
||||
/**
|
||||
* JMenuU的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuUI
|
||||
*/
|
||||
public class BEMenuUI extends BasicMenuUI {
|
||||
|
||||
//JMenuBar的顶层菜单项的装饰底线高度
|
||||
public final static int DECORATED_UNDERLINE_HEIGHT = 2;// TODO 可以提炼成Ui属性哦
|
||||
|
||||
//顶层菜单项被选中的颜色
|
||||
public final static Color MENU_SELECTED_UNDERLINE_COLOR = new Color(37, 147, 217);// TODO 可以提炼成Ui属性哦
|
||||
|
||||
//顶层菜单项未被选中的颜色
|
||||
public final static Color MENU_UNSELECTED_UNDERLINE_COLOR = new Color(226, 230, 232);// TODO 可以提炼成Ui属性哦
|
||||
|
||||
protected Integer menuBarHeight;
|
||||
|
||||
protected boolean hotTrackingOn;
|
||||
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new BEMenuUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuUI#installDefaults()
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
// if (!WindowsLookAndFeel.isClassicWindows())
|
||||
{
|
||||
menuItem.setRolloverEnabled(true);
|
||||
}
|
||||
|
||||
menuBarHeight = (Integer) UIManager.getInt("MenuBar.height");
|
||||
Object obj = UIManager.get("MenuBar.rolloverEnabled");
|
||||
hotTrackingOn = (obj instanceof Boolean) ? (Boolean) obj : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the background of the menu.
|
||||
*
|
||||
* @param g the g
|
||||
* @param menuItem the menu item
|
||||
* @param bgColor the bg color
|
||||
* @since 1.4
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuUI#paintBackground(java.awt.Graphics, javax.swing.JMenuItem, java.awt.Color)
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
|
||||
JMenu menu = (JMenu) menuItem;
|
||||
ButtonModel model = menu.getModel();
|
||||
|
||||
Color oldColor = g.getColor();
|
||||
int menuWidth = menu.getWidth();
|
||||
int menuHeight = menu.getHeight();
|
||||
|
||||
// UIDefaults table = UIManager.getLookAndFeelDefaults();
|
||||
// Color highlight = table.getColor("controlLtHighlight");
|
||||
// Color shadow = table.getColor("controlShadow");
|
||||
g.setColor(menu.getBackground());
|
||||
g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
|
||||
//给JMEnuBar的顶层菜单项中画一个灰色底线(看起来美观)
|
||||
//位于菜单项里的MenuItem则不需要画这个底线(要不然不好看哦)
|
||||
if (menu.isTopLevelMenu()) {
|
||||
//未选中的装饰底线
|
||||
//只要放在MenuBar最顶层的JMenu才需要画哦(从而与底色融为一体)
|
||||
g.setColor(MENU_UNSELECTED_UNDERLINE_COLOR);
|
||||
g.fillRect(0, menuHeight - DECORATED_UNDERLINE_HEIGHT, menuWidth, menuHeight);
|
||||
}
|
||||
|
||||
//* >注意:官方是判断menu.isOpaque()==false时才进入此if-else分支,
|
||||
//* >其实以下代码的意义是:当是顶级Menu(即直接放在MenuBar上的那层)时
|
||||
//* >才需要调用以下分支,而在win7下,以下分支是不会被调用的(WindowsLookAndfeel.initVistaComponentDefaults中
|
||||
//* >处理了如果是vista则"MenuItem.opaque", "Menu.opaque", "CheckBoxMenuItem.opaque", "RadioButtonMenuItem.opaque"
|
||||
//* >默认都设置成了false,即默认透明(官方逻辑可能是透明体就意味着是顶级menu了)!)
|
||||
//* >,那么win7下将会出现错误的表现:无法区分是不是顶级menu也就无法区别paint出不同的样子了.
|
||||
//* >那么官方为何没收到bug报告呢?我分析可能还没有人面对到BeautyEye这样需要对Menu进行较复杂样式需求的场景
|
||||
//* >,即把顶级menu和内层menu分的很清。
|
||||
//* >目前BeautyEye的实现即menu.isTopLevelMenu()==true时即进入本分支
|
||||
//* >才是比较合理的,当然,有待实践检验,或许官方有其它考虑。 -- commet by Jack Jiang 2012-09-14
|
||||
if (menu.isTopLevelMenu())//menu.isOpaque())
|
||||
{
|
||||
//JMebuBar的顶层菜单项被选中或鼠标停留时
|
||||
if (model.isArmed() || model.isSelected()) {
|
||||
Color c = MENU_SELECTED_UNDERLINE_COLOR;
|
||||
g.setColor(c);
|
||||
|
||||
//先填充一个装饰3角形(用于在UI上提示用户它被选中了)
|
||||
// x2,y2
|
||||
//
|
||||
//x1,y1 x3,y3
|
||||
int tW = 7, tH = 3;
|
||||
int x1 = menuWidth / 2 - tW / 2;
|
||||
int y1 = menuHeight - DECORATED_UNDERLINE_HEIGHT;
|
||||
int x2 = menuWidth / 2;
|
||||
int y2 = menuHeight - DECORATED_UNDERLINE_HEIGHT - tH;
|
||||
int x3 = menuWidth / 2 + tW / 2;
|
||||
int y3 = menuHeight - DECORATED_UNDERLINE_HEIGHT;
|
||||
//反走样
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, true);
|
||||
BEUtils.fillTriangle(g, x1, y1, x2, y2, x3, y3, c);
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, false);
|
||||
|
||||
//再填充一个底线(用于装饰)
|
||||
g.fillRect(0, menuHeight - DECORATED_UNDERLINE_HEIGHT, menuWidth, DECORATED_UNDERLINE_HEIGHT);//menuHeight);
|
||||
} else if (model.isRollover() && model.isEnabled()) {
|
||||
// Only paint rollover if no other menu on menubar is selected
|
||||
boolean otherMenuSelected = false;
|
||||
MenuElement[] menus = ((JMenuBar) menu.getParent())
|
||||
.getSubElements();
|
||||
for (MenuElement menu1 : menus)
|
||||
if (((JMenuItem) menu1).isSelected()) {
|
||||
otherMenuSelected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!otherMenuSelected) {
|
||||
g.setColor(MENU_SELECTED_UNDERLINE_COLOR);//selectionBackground);// Uses protected
|
||||
// g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
//再填充一个底线(用于装饰)
|
||||
g.fillRect(0, menuHeight - DECORATED_UNDERLINE_HEIGHT, menuWidth, DECORATED_UNDERLINE_HEIGHT);//menuHeight);
|
||||
}
|
||||
}
|
||||
} // add by Jack Jiang,JMebuBar的内层父级菜单项的样式绘制
|
||||
else if (model.isArmed() || (menuItem instanceof JMenu
|
||||
&& model.isSelected())) {
|
||||
//用NinePatch图来填充
|
||||
drawSelectedBackground(g, 0, 0, menuWidth, menuHeight);
|
||||
}
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
|
||||
public static void drawSelectedBackground(Graphics g, int x, int y, int w, int h) {
|
||||
g.setColor(UIManager.getColor("MenuItem.selectionBackground"));
|
||||
g.fillRect(0, 0, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which renders the text of the current menu item.
|
||||
* <p>
|
||||
* @param g Graphics context
|
||||
* @param menuItem Current menu item to render
|
||||
* @param textRect Bounding rectangle to render the text.
|
||||
* @param text String to render
|
||||
* @since 1.4
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuUI#paintText(java.awt.Graphics, javax.swing.JMenuItem, java.awt.Rectangle, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void paintText(Graphics g, JMenuItem menuItem,
|
||||
Rectangle textRect, String text) {
|
||||
//================= commet by Jack Jiang START
|
||||
// if (WindowsMenuItemUI.isVistaPainting()) {
|
||||
// WindowsMenuItemUI.paintText(accessor, g, menuItem, textRect, text);
|
||||
// return;
|
||||
// }
|
||||
//================= commet by Jack Jiang END
|
||||
JMenu menu = (JMenu) menuItem;
|
||||
ButtonModel model = menuItem.getModel();
|
||||
Color oldColor = g.getColor();
|
||||
|
||||
// Only paint rollover if no other menu on menubar is selected
|
||||
boolean paintRollover = model.isRollover();
|
||||
if (paintRollover && menu.isTopLevelMenu()) {
|
||||
MenuElement[] menus = ((JMenuBar) menu.getParent()).getSubElements();
|
||||
for (MenuElement menu1 : menus)
|
||||
if (((JMenuItem) menu1).isSelected()) {
|
||||
paintRollover = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((model.isSelected()
|
||||
&& ( // WindowsLookAndFeel.isClassicWindows() ||
|
||||
!menu.isTopLevelMenu()))
|
||||
|| ( // BEXPStyle.getXP() != null &&
|
||||
(paintRollover || model.isArmed() || model.isSelected())))
|
||||
g.setColor(selectionForeground); // Uses protected field.
|
||||
|
||||
//================= add by Jack Jiang START
|
||||
//特殊处理顶级菜单项(就是直接放在JMenuBar上的那一层),使之在被选中或rover等状态时保持黑色(或其它颜色)
|
||||
//,目的是为了配合整个菜单项的L&F效果,并没有过多的用途,此颜色可提取作为UIManager的自定义属性哦
|
||||
if (menu.isTopLevelMenu())
|
||||
g.setColor(new Color(35, 35, 35));//用MaxOS X的经典黑
|
||||
//================= add by Jack Jiang END
|
||||
|
||||
// WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0);
|
||||
WinUtils.paintText(g, menuItem, textRect, text, 0);
|
||||
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see
|
||||
* com.sun.java.swing.plaf.windows.WindowsMenuUI#createMouseInputListener(javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
protected MouseInputListener createMouseInputListener(JComponent c) {
|
||||
return new BEMouseInputHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements a mouse handler that sets the rollover flag to true
|
||||
* when the mouse enters the menu and false when it exits.
|
||||
*
|
||||
* @since 1.4
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsMenuUI.MouseInputHandler
|
||||
*/
|
||||
protected class BEMouseInputHandler extends BasicMenuUI.MouseInputHandler {
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent evt) {
|
||||
super.mouseEntered(evt);
|
||||
|
||||
JMenu menu = (JMenu) evt.getSource();
|
||||
if (hotTrackingOn && menu.isTopLevelMenu() && menu.isRolloverEnabled()) {
|
||||
menu.getModel().setRollover(true);
|
||||
menuItem.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent evt) {
|
||||
super.mouseExited(evt);
|
||||
|
||||
JMenu menu = (JMenu) evt.getSource();
|
||||
ButtonModel model = menu.getModel();
|
||||
if (menu.isRolloverEnabled()) {
|
||||
model.setRollover(false);
|
||||
menuItem.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see
|
||||
* com.sun.java.swing.plaf.windows.WindowsMenuUI#getPreferredMenuItemSize(javax.swing.JComponent,
|
||||
* javax.swing.Icon, javax.swing.Icon, int)
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getPreferredMenuItemSize(JComponent c,
|
||||
Icon checkIcon,
|
||||
Icon arrowIcon,
|
||||
int defaultTextIconGap) {
|
||||
|
||||
Dimension d = super.getPreferredMenuItemSize(c, checkIcon, arrowIcon,
|
||||
defaultTextIconGap);
|
||||
|
||||
// Note: When toolbar containers (rebars) are implemented, only do
|
||||
// this if the JMenuBar is not in a rebar (i.e. ignore the desktop
|
||||
// property win.menu.height if in a rebar.)
|
||||
if (c instanceof JMenu && ((JMenu) c).isTopLevelMenu()
|
||||
&& menuBarHeight != null && d.height < menuBarHeight)
|
||||
|
||||
d.height = menuBarHeight;
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEPopupMenuSeparatorUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.SeparatorUI;
|
||||
|
||||
/**
|
||||
* JPopupMenuSeparator的UI实现.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BEPopupMenuSeparatorUI extends SeparatorUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEPopupMenuSeparatorUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
installDefaults((JSeparator) c);
|
||||
installListeners((JSeparator) c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
uninstallDefaults((JSeparator) c);
|
||||
uninstallListeners((JSeparator) c);
|
||||
}
|
||||
|
||||
protected void installDefaults(JSeparator s) {
|
||||
LookAndFeel.installColors(s, "Separator.background", "Separator.foreground");
|
||||
LookAndFeel.installProperty(s, "opaque", Boolean.FALSE);
|
||||
}
|
||||
|
||||
protected void uninstallDefaults(JSeparator s) {
|
||||
}
|
||||
|
||||
protected void installListeners(JSeparator s) {
|
||||
}
|
||||
|
||||
protected void uninstallListeners(JSeparator s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
int w = c.getWidth(), h = c.getHeight();
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
if (((JSeparator) c).getOrientation() == JSeparator.VERTICAL) {
|
||||
//垂直坚线原始代码
|
||||
//TODO 垂直样式的竖线有时间再实现吧,垂直竖线默认用于JToolBar里
|
||||
g.setColor(c.getForeground());
|
||||
g.drawLine(0, 0, 0, c.getHeight());
|
||||
g.setColor(c.getBackground());
|
||||
g.drawLine(1, 0, 1, c.getHeight());
|
||||
} else // HORIZONTAL
|
||||
|
||||
drawHorizonal(g2, c, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以水平方向绘制分隔线样式.
|
||||
*/
|
||||
private void drawHorizonal(Graphics2D g2, JComponent c, int w, int h) {
|
||||
//** 绘制border的底线
|
||||
//虚线样式
|
||||
Stroke oldStroke = g2.getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
g2.setStroke(sroke);
|
||||
//底边上(浅灰色)
|
||||
// g2.setColor(new Color(180,180,180));
|
||||
g2.setColor(c.getForeground());
|
||||
g2.drawLine(0, h - 2, w - 1, h - 2); // draw bottom1
|
||||
//底边下(白色):绘制一条白色虚线的目的是与上面的灰线产生较强对比度从而形成立体效果
|
||||
//,本L&F实现中因与Panel的底色对比度不够强烈而立体感不明显(颜色越深的底色最终效果越明显)
|
||||
// g2.setColor(Color.white);
|
||||
g2.setColor(c.getBackground());
|
||||
g2.drawLine(0, h - 1, w - 1, h - 1);//draw bottom2
|
||||
|
||||
g2.setStroke(oldStroke);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
if (((JSeparator) c).getOrientation() == JSeparator.VERTICAL)
|
||||
return new Dimension(2, 0);
|
||||
else
|
||||
return new Dimension(0, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize(JComponent c) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEPopupMenuUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicPopupMenuUI;
|
||||
|
||||
/**
|
||||
* BeautyEye L&F的弹出菜单主类实现类.
|
||||
*
|
||||
* 兼容性说明:WindowsPopupMenuUI类在java1.6.0_u10(可能不仅限于1.6.0_u10,但java1.6.0中不存在这个问题)
|
||||
* 中会判断,如果是在Vista或者说xp平台时(测试证明是在win7平台会有这些问题)会用windows系
|
||||
* 统实现进行背景填充,而在1.6.0_u18(可能不限于此版本中)取消了这样的判断,改为直接继续
|
||||
* BasicPopupMenuUI的实默认实现。因此而带来的差异使得BE LNF在不同的java版本里(u10)会
|
||||
* 错误地使用windows系统实现.本类的目的就是要去掉这种差异,仍然交由父类BasicPopupMenuUI 实现即可(类似的官方Metal
|
||||
* LNF也是采用了BeautyEye一样的处理逻辑).
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-09-14
|
||||
* @version 1.0
|
||||
* @since 3.1
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsPopupMenuUI
|
||||
*/
|
||||
public class BEPopupMenuUI extends BasicPopupMenuUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEPopupMenuUI();
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BERadioButtonMenuItemUI.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
|
||||
/**
|
||||
* JRadioButtonMenuItem的UI实现.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BERadioButtonMenuItemUI extends BasicRadioButtonMenuItemUI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("menu_radio");
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new BERadioButtonMenuItemUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the background of the menu item.
|
||||
*
|
||||
* @param g the paint graphics
|
||||
* @param menuItem menu item to be painted
|
||||
* @param bgColor selection background color
|
||||
* @since 1.4
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicMenuItemUI#paintBackground(java.awt.Graphics,
|
||||
* javax.swing.JMenuItem, java.awt.Color)
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
|
||||
ButtonModel model = menuItem.getModel();
|
||||
Color oldColor = g.getColor();
|
||||
int menuWidth = menuItem.getWidth();
|
||||
int menuHeight = menuItem.getHeight();
|
||||
|
||||
if (menuItem.isOpaque()) {
|
||||
if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) {
|
||||
g.setColor(bgColor);
|
||||
g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
} else {
|
||||
g.setColor(menuItem.getBackground());
|
||||
g.fillRect(0, 0, menuWidth, menuHeight);
|
||||
}
|
||||
g.setColor(oldColor);
|
||||
} else if (model.isArmed() || (menuItem instanceof JMenu
|
||||
&& model.isSelected()))
|
||||
// g.setColor(bgColor);
|
||||
// g.fillRect(0,0, menuWidth, menuHeight);
|
||||
// g.setColor(oldColor);
|
||||
|
||||
//由jb2011改用NinePatch图来填充
|
||||
BEMenuUI.drawSelectedBackground(g, 0, 0, menuWidth, menuHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsIconFactory.RadioButtonMenuItemIcon
|
||||
*/
|
||||
public static class RadioButtonMenuItemIcon implements Icon, UIResource, Serializable {
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
//* 注意:当用于windows平台专用主类且处于Vista及更高版win时要做不一样的处理哦
|
||||
g.drawImage(ICON.get(((AbstractButton) c).getModel().isSelected() ? "checked" : "normal").getImage(),
|
||||
x - 4, y - 4, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return 16;
|
||||
}//default 6
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return 16;
|
||||
}//default 6
|
||||
|
||||
}
|
||||
}
|
105
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/menu/__UI__.java
Normal file
105
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/menu/__UI__.java
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.menu;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> margin和border设置 START
|
||||
// UIManager.put("MenuBar.border",new org.jb2011.lnf.windows2.ch10.EWindowsMenuBarUI.MenuBarBorder(Color.red,Color.BLUE));
|
||||
//去掉菜单条下方的border(默认是一个2个像素高的横线,参见WindowsMenuBarUI.MenuBarBorder)
|
||||
putBorder("MenuBar.border");
|
||||
|
||||
//提示:margin与border并存设置情况容易产生混知,其实官方实现是:当设置margin时,则Border就使用
|
||||
//marginBorder,该Border就是用的这个margin来作它的Insets的
|
||||
//BueatyEye LNF中推荐实践是:抛弃margin的概念(省的混淆),直接使用border(在其上直接给于insets)即可
|
||||
putInsets("CheckBoxMenuItem.margin", 0, 0, 0, 0);
|
||||
putInsets("RadioButtonMenuItem.margin", 0, 0, 0, 0);//iuir);
|
||||
putInsets("Menu.margin", 0, 0, 0, 0);//windows lnf中默认是2,2,2,2
|
||||
putInsets("MenuItem.margin", 0, 0, 0, 0);//windows lnf中默认是2,2,2,2
|
||||
// putInsets("MenuItem.margin", 10, 2, 10, 2);//top=2,left=2,bottom=2,right=2
|
||||
|
||||
//请注意:上面的margin已经全设为0了哦
|
||||
putBorder("Menu.border", 4, 3, 5, 3);//javax.swing.plaf.basic.BasicBorders.MarginBorder;
|
||||
putBorder("MenuItem.border", 4, 3, 5, 3);//
|
||||
putBorder("CheckBoxMenuItem.border", 4, 3, 5, 3);//javax.swing.plaf.basic.BasicBorders.MarginBorder;
|
||||
putBorder("RadioButtonMenuItem.border", 4, 3, 5, 3);//
|
||||
// putBorder("PopupMenu.border", 20, 10, 20, 10); //
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> margin和border设置 END
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 颜色设置 START
|
||||
put("MenuBar.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("RadioButtonMenuItem.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("Menu.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("PopupMenu.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("CheckBoxMenuItem.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("MenuItem.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
put("MenuBar.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("Menu.background", new Color(255, 255, 255, 0));
|
||||
put("PopupMenu.background", new Color(255, 255, 255, 0));
|
||||
|
||||
put("RadioButtonMenuItem.disabledForeground", BeautyEyeLNFHelper.commonDisabledForegroundColor);
|
||||
put("MenuItem.disabledForeground", BeautyEyeLNFHelper.commonDisabledForegroundColor);
|
||||
|
||||
put("Menu.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("MenuItem.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("CheckBoxMenuItem.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("RadioButtonMenuItem.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
|
||||
put("Menu.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("MenuItem.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("CheckBoxMenuItem.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("RadioButtonMenuItem.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 颜色设置 END
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 杂项设置 START
|
||||
//本值意味着弹出菜单X轴方向上的偏移量,因BE LNF中加了边框,所以要负偏移以便得弹出菜单主体能与菜单项对齐好看一些
|
||||
put("Menu.menuPopupOffsetX", -3);//win lnf中默认值是0
|
||||
//本值意味着弹出菜单Y轴方向上的偏移量,因BE LNF中加了边框,所以要负偏移以便得弹出菜单主体能与菜单项对齐好看一些
|
||||
put("Menu.menuPopupOffsetY", 2);///win lnf默认值是0
|
||||
//本值意味着弹出子菜单X轴方向上的偏移量,因BE LNF中加了边框,所以要负偏移以便得弹出菜单主体能与菜单项对齐好看一些
|
||||
put("Menu.submenuPopupOffsetX", -2);///win lnf默认值是-4
|
||||
//本值意味着弹出子菜单Y轴方向上的偏移量,因BE LNF中加了边框,所以要负偏移以便得弹出菜单主体能与菜单项对齐好看一些
|
||||
put("Menu.submenuPopupOffsetY", -5);///win lnf默认值是-3
|
||||
|
||||
//多选按钮式的菜单项选中与否的图标实现设定
|
||||
UIManager.put("CheckBoxMenuItem.checkIcon", new BECheckBoxMenuItemUI.CheckBoxMenuItemIcon());
|
||||
//单选按钮式的菜单项选中与否的图标实现设定
|
||||
UIManager.put("RadioButtonMenuItem.checkIcon", new BERadioButtonMenuItemUI.RadioButtonMenuItemIcon());
|
||||
|
||||
//加高菜单条,提升视觉体验
|
||||
put("MenuBar.height", 30);//default value is 19
|
||||
|
||||
//此属性true时表明禁用的菜单项将不能被rover,否则有rover效果(BE LNF中
|
||||
//因禁用状态rover时的字体色影响视觉效果,所以干脆禁用之,逻辑上也很合理)
|
||||
put("MenuItem.disabledAreNavigable", false);// windows lnf中默认是true
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 杂项设置 END
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> UI实现类设置 START
|
||||
put("MenuBarUI", BEMenuBarUI.class);
|
||||
put("MenuUI", BEMenuUI.class);
|
||||
put("MenuItemUI", BEMenuItemUI.class);
|
||||
put("RadioButtonMenuItemUI", BERadioButtonMenuItemUI.class);
|
||||
put("CheckBoxMenuItemUI", BECheckBoxMenuItemUI.class);
|
||||
put("PopupMenuSeparatorUI", BEPopupMenuSeparatorUI.class);
|
||||
put("PopupMenuUI", BEPopupMenuUI.class);
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> UI实现类设置 END
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
/*
|
||||
* $Id: MetroGraphicsUtils.java,v 1.9 2005/12/05 15:00:55 kizune Exp $
|
||||
*
|
||||
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
* Santa Clara, California 95054, U.S.A. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.painter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.plaf.synth.SynthConstants;
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthPainter;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
import org.jackhuang.hmcl.laf.ConstomButton;
|
||||
|
||||
/**
|
||||
* ButtonPainter - handles painting Nimbus style buttons with Java2D
|
||||
*
|
||||
* @author Created by Jasper Potts (Jan 4, 2007)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ButtonPainter extends SynthPainter {
|
||||
|
||||
private static final String DEFAULT_NORMAL = "D5D5D5";
|
||||
private static final Color[] DEFAULT_NORMAL_FG = new Color[]{
|
||||
GraphicsUtils.getWebColor(DEFAULT_NORMAL),
|
||||
GraphicsUtils.getWebColor(DEFAULT_NORMAL)
|
||||
};
|
||||
private static final String DEFAULT_PRELIGHT = "A9A9A9";
|
||||
private static final Color[] DEFAULT_PRELIGHT_FG = new Color[]{
|
||||
GraphicsUtils.getWebColor(DEFAULT_PRELIGHT),
|
||||
GraphicsUtils.getWebColor(DEFAULT_PRELIGHT)
|
||||
};
|
||||
private static final String DEFAULT_ACTIVE = "222222";
|
||||
private static final Color[] DEFAULT_ACTIVE_FG = new Color[]{
|
||||
GraphicsUtils.getWebColor(DEFAULT_ACTIVE),
|
||||
GraphicsUtils.getWebColor(DEFAULT_ACTIVE)
|
||||
};
|
||||
|
||||
private static final Color[] DISABLED_BG = new Color[]{
|
||||
GraphicsUtils.getWebColor("E3EFE9"),
|
||||
GraphicsUtils.getMidWebColor("E3EFE9", "DFE2E6"),
|
||||
GraphicsUtils.getWebColor("DFE2E6"),
|
||||
GraphicsUtils.getMidWebColor("DFE2E6", "D6D9DF"),
|
||||
GraphicsUtils.getWebColor("D6D9DF"),
|
||||
GraphicsUtils.getWebColor("D6D9DF"),
|
||||
GraphicsUtils.getMidWebColor("D6D9DF", "D8DBE1"),
|
||||
GraphicsUtils.getWebColor("D8DBE1"),
|
||||
GraphicsUtils.getWebColor("DADDE3")
|
||||
};
|
||||
private static final Color[] DISABLED_FG = new Color[]{
|
||||
GraphicsUtils.getWebColor("C9CCD2"),
|
||||
GraphicsUtils.getWebColor("C9CCD2"),
|
||||
GraphicsUtils.getWebColor("BCBFC5"),
|
||||
GraphicsUtils.getWebColor("BCBFC5")
|
||||
};
|
||||
|
||||
private static boolean processCustomButton(final ConstomButton c, int add) {
|
||||
if (c.drawPercent == 0 || c.drawPercent == 100) {
|
||||
Timer t = new Timer(1, null);
|
||||
t.addActionListener(x -> {
|
||||
c.drawPercent += add;
|
||||
if (c.drawPercent > 100 && add > 0) {
|
||||
c.drawPercent = 100;
|
||||
t.stop();
|
||||
} else if (c.drawPercent < 0 && add < 0) {
|
||||
c.drawPercent = 0;
|
||||
t.stop();
|
||||
} else
|
||||
c.updateUI();
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
Color[] fg, bg;
|
||||
if ((context.getComponentState() & SynthConstants.DEFAULT) != 0)
|
||||
if ((context.getComponentState() & SynthConstants.PRESSED) != 0)
|
||||
if (context.getComponent() instanceof ConstomButton) {
|
||||
ConstomButton c = (ConstomButton) context.getComponent();
|
||||
fg = new Color[]{c.activeFg, c.activeFg};
|
||||
bg = new Color[]{c.activeFg, c.activeFg};
|
||||
} else {
|
||||
fg = DEFAULT_ACTIVE_FG;
|
||||
bg = DEFAULT_ACTIVE_FG;
|
||||
}
|
||||
else if ((context.getComponentState() & SynthConstants.DISABLED) != 0)
|
||||
return; //fg = DISABLED_FG;
|
||||
//bg = DISABLED_BG;
|
||||
else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0)
|
||||
if (context.getComponent() instanceof ConstomButton) {
|
||||
final ConstomButton c = (ConstomButton) context.getComponent();
|
||||
if (!processCustomButton(c, 1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[]{fgs, fgs};
|
||||
bg = new Color[]{bgs, bgs};
|
||||
} else {
|
||||
fg = DEFAULT_PRELIGHT_FG;
|
||||
bg = DEFAULT_PRELIGHT_FG;
|
||||
}
|
||||
else if (context.getComponent() instanceof ConstomButton) {
|
||||
final ConstomButton c = (ConstomButton) context.getComponent();
|
||||
if (!processCustomButton(c, -1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[]{fgs, fgs};
|
||||
bg = new Color[]{bgs, bgs};
|
||||
} else {
|
||||
fg = DEFAULT_NORMAL_FG;
|
||||
bg = DEFAULT_NORMAL_FG;
|
||||
}
|
||||
else if ((context.getComponentState() & SynthConstants.PRESSED) != 0)
|
||||
if (context.getComponent() instanceof ConstomButton) {
|
||||
ConstomButton c = (ConstomButton) context.getComponent();
|
||||
fg = new Color[]{c.activeFg, c.activeFg};
|
||||
bg = new Color[]{c.activeFg, c.activeFg};
|
||||
} else {
|
||||
fg = DEFAULT_ACTIVE_FG;
|
||||
bg = DEFAULT_ACTIVE_FG;
|
||||
}
|
||||
else if ((context.getComponentState() & SynthConstants.DISABLED) != 0)
|
||||
return; //fg = DISABLED_FG;
|
||||
//bg = DISABLED_BG;
|
||||
else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0)
|
||||
if (context.getComponent() instanceof ConstomButton) {
|
||||
final ConstomButton c = (ConstomButton) context.getComponent();
|
||||
if (!processCustomButton(c, 1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[]{fgs, fgs};
|
||||
bg = new Color[]{bgs, bgs};
|
||||
} else if (context.getComponent() instanceof ConstomButton) {
|
||||
ConstomButton c = (ConstomButton) context.getComponent();
|
||||
fg = new Color[]{c.prelightFg, c.prelightFg};
|
||||
bg = new Color[]{c.prelightBg, c.prelightBg};
|
||||
} else {
|
||||
fg = DEFAULT_PRELIGHT_FG;
|
||||
bg = DEFAULT_PRELIGHT_FG;
|
||||
}
|
||||
else if (context.getComponent() instanceof ConstomButton) {
|
||||
final ConstomButton c = (ConstomButton) context.getComponent();
|
||||
if (!processCustomButton(c, -1))
|
||||
return;
|
||||
Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent);
|
||||
Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent);
|
||||
fg = new Color[]{fgs, fgs};
|
||||
bg = new Color[]{bgs, bgs};
|
||||
} else {
|
||||
fg = DEFAULT_NORMAL_FG;
|
||||
bg = DEFAULT_NORMAL_FG;
|
||||
}
|
||||
/*w = w - 2;
|
||||
h = h - 2;
|
||||
|
||||
g2.setPaint(new LinearGradientPaint(x, y, x, y + h,
|
||||
new float[]{0, 1}, bg));
|
||||
g2.fillRect(x, y, w, h);
|
||||
|
||||
g2.setPaint(new LinearGradientPaint(x, y, x, y + h,
|
||||
new float[]{0, 1}, fg));
|
||||
g2.drawRect(x, y, w, h);*/
|
||||
|
||||
int radix = (context.getComponent() instanceof ConstomButton) ? ((ConstomButton) context.getComponent()).radix : 0;
|
||||
|
||||
g2.setColor(fg[0]);
|
||||
RoundRectangle2D fgshape = new RoundRectangle2D.Float(x, y, w, h, radix, radix);
|
||||
g2.draw(fgshape);
|
||||
g2.setColor(bg[0]);
|
||||
RoundRectangle2D bgshape = new RoundRectangle2D.Float(x, y, w, h, radix, radix);
|
||||
g2.fill(bgshape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintToggleButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
Color[] fg, bg;
|
||||
//if ((context.getComponentState() & SynthConstants.DEFAULT) != 0)
|
||||
if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) {
|
||||
fg = DEFAULT_ACTIVE_FG;
|
||||
bg = DEFAULT_ACTIVE_FG;
|
||||
} else if ((context.getComponentState() & SynthConstants.DISABLED) != 0) {
|
||||
fg = DISABLED_FG;
|
||||
bg = DISABLED_BG;
|
||||
} else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0) {
|
||||
fg = DEFAULT_PRELIGHT_FG;
|
||||
bg = DEFAULT_PRELIGHT_FG;
|
||||
} else {
|
||||
fg = DEFAULT_NORMAL_FG;
|
||||
bg = DEFAULT_NORMAL_FG;
|
||||
}
|
||||
/*else if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) {
|
||||
fg = DEFAULT_ACTIVE_FG;
|
||||
bg = DEFAULT_ACTIVE_FG;
|
||||
} else if ((context.getComponentState() & SynthConstants.DISABLED) != 0) {
|
||||
fg = DISABLED_FG;
|
||||
bg = DISABLED_BG;
|
||||
} else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0) {
|
||||
fg = DEFAULT_PRELIGHT_FG;
|
||||
bg = DEFAULT_PRELIGHT_FG;
|
||||
} else {
|
||||
fg = DEFAULT_NORMAL_FG;
|
||||
bg = DEFAULT_NORMAL_FG;
|
||||
}*/
|
||||
g2.setColor(fg[0]);
|
||||
Rectangle2D fgshape = new Rectangle2D.Float(x, y, w, h);
|
||||
g2.draw(fgshape);
|
||||
g2.setColor(bg[0]);
|
||||
Rectangle2D bgshape = new Rectangle2D.Float(x, y, w, h);
|
||||
g2.fill(bgshape);
|
||||
|
||||
/*g2.setPaint(new LinearGradientPaint(x, y, x, y + h,
|
||||
new float[]{0, 1}, bg));
|
||||
g2.fillRect(x, y, w, h);
|
||||
|
||||
g2.setPaint(new LinearGradientPaint(x, y, x, y + h,
|
||||
new float[]{0, 1}, fg));
|
||||
g2.drawRect(x, y, w, h);*/
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* $Id: MetroGraphicsUtils.java,v 1.9 2005/12/05 15:00:55 kizune Exp $
|
||||
*
|
||||
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
* Santa Clara, California 95054, U.S.A. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.painter;
|
||||
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthPainter;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.LinearGradientPaint;
|
||||
|
||||
/**
|
||||
* ProgressPainter - Synth painter for Nimbus progressbars
|
||||
*
|
||||
* @author Created by Jasper Potts (Jan 3, 2007)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ProgressPainter extends SynthPainter {
|
||||
|
||||
private static final float[] NORMAL_BG_PTS = new float[]{0, 1};
|
||||
private static final Color[] NORMAL_BG = new Color[]{
|
||||
GraphicsUtils.getWebColor("c6c6c6"),
|
||||
GraphicsUtils.getWebColor("c6c6c6")
|
||||
};
|
||||
private static final float[] BAR_FG_PTS = new float[]{0, 1};
|
||||
private static final Color[] BAR_FG = new Color[]{
|
||||
GraphicsUtils.getWebColor("41B1E1"),
|
||||
GraphicsUtils.getWebColor("41B1E1")
|
||||
};
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintProgressBarBackground(SynthContext context, Graphics g, int x, int y, int w, int h,
|
||||
int orientation) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setPaint(new LinearGradientPaint(x, y + 2, x, y + h - 4, NORMAL_BG_PTS, NORMAL_BG));
|
||||
if (x + 2 < w - 5 && y + 2 < h - 5)
|
||||
g2.fillRect(x + 2, y + 2, w - 5, h - 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintProgressBarForeground(SynthContext context, Graphics g, int x, int y, int w, int h,
|
||||
int orientation) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setPaint(new LinearGradientPaint(x, y + 2, x, y + h - 2, BAR_FG_PTS, BAR_FG));
|
||||
if (x + 2 < w - 5 && y + 2 < h - 5)
|
||||
g2.fillRect(x + 2, y + 2, w - 5, h - 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paintProgressBarBorder(SynthContext context, Graphics g, int x, int y, int w, int h, int orientation) {
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* $Id: NimbusGraphicsUtils.java,v 1.9 2005/12/05 15:00:55 kizune Exp $
|
||||
*
|
||||
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
* Santa Clara, California 95054, U.S.A. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.painter;
|
||||
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
import javax.swing.plaf.synth.SynthPainter;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.plaf.synth.SynthConstants;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
|
||||
/**
|
||||
* TextFieldPainter
|
||||
*
|
||||
* @author Created by Jasper Potts (Jan 4, 2007)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TextFieldPainter extends SynthPainter {
|
||||
|
||||
private boolean fill = true;
|
||||
|
||||
private static final Color DISABLED = GraphicsUtils.getWebColor("F3F3F3"),
|
||||
NORMAL = GraphicsUtils.getWebColor("CCCCCC"),
|
||||
FOCUSED = GraphicsUtils.getWebColor("000000"),
|
||||
OVER = GraphicsUtils.getWebColor("7F7F7F");
|
||||
|
||||
public TextFieldPainter() {
|
||||
}
|
||||
|
||||
public TextFieldPainter(boolean fill) {
|
||||
this.fill = fill;
|
||||
}
|
||||
|
||||
private void paintFieldBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
w--;
|
||||
h--;
|
||||
if (fill) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(x, y, w, h);
|
||||
}
|
||||
Color color;
|
||||
if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0)
|
||||
color = OVER;
|
||||
else if ((context.getComponentState() & SynthConstants.DISABLED) != 0)
|
||||
color = DISABLED;
|
||||
else if ((context.getComponentState() & SynthConstants.FOCUSED) != 0)
|
||||
color = FOCUSED;
|
||||
else
|
||||
color = NORMAL;
|
||||
g.setColor(color);
|
||||
g.drawLine(x, y, x + w, y);
|
||||
g.drawLine(x, y, x, y + w);
|
||||
g.drawLine(x + w, y, x + w, y + h);
|
||||
g.drawLine(x, y + h, x + w, y + h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintPasswordFieldBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
paintFieldBackground(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintTextAreaBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
paintFieldBackground(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintTextFieldBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
paintFieldBackground(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintTextPaneBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
paintFieldBackground(context, g, x, y, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintScrollPaneBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
|
||||
paintFieldBackground(context, g, x, y, w, h);
|
||||
}
|
||||
}
|
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* TranslucentPopupFactory.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.popup;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Window;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import org.jackhuang.hmcl.laf.scroll.BEScrollBarUI;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.WindowTranslucencyHelper;
|
||||
import org.jackhuang.hmcl.laf.widget.ImageBgPanel;
|
||||
|
||||
/**
|
||||
* 自定义透明背景的弹出工厂实现类.
|
||||
*
|
||||
* 本类其实与Swing的UI机制关联不大,完全可以独立于L&F使用。
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-05-18
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TranslucentPopupFactory extends PopupFactory {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("popup");
|
||||
|
||||
@Override
|
||||
public Popup getPopup(Component owner, Component contents, int x, int y)
|
||||
throws IllegalArgumentException {
|
||||
// A more complete implementation would cache and reuse popups
|
||||
return new TranslucentPopup(owner, contents, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* 透明背景的Popup实现类.
|
||||
* <p>
|
||||
* 本类的大部分代码都是原封不动地参考自Popup父类(JDK版本是1.6_u18版的源码),因为Popup父
|
||||
* 类中的多数方法都是使用的包内可见性,所以没法直接继承,像这种不允许第3方自行扩展的情
|
||||
* 况在Swing标准包里比较少见,不知原作者是出于何种考虑,无疑这样的类实现是相当的欠缺远 见性,但这种情况在LNF里很常见。
|
||||
*/
|
||||
protected class TranslucentPopup extends Popup {
|
||||
//copy all from parent class
|
||||
|
||||
/**
|
||||
* The Component representing the Popup.
|
||||
*/
|
||||
private Component component;
|
||||
|
||||
//copy all from parent class
|
||||
/**
|
||||
* Creates a <code>Popup</code> for the Component <code>owner</code>
|
||||
* containing the Component <code>contents</code>. <code>owner</code> is
|
||||
* used to determine which <code>Window</code> the new
|
||||
* <code>Popup</code> will parent the <code>Component</code> the
|
||||
* <code>Popup</code> creates to. A null <code>owner</code> implies
|
||||
* there is no valid parent. <code>x</code> and <code>y</code> specify
|
||||
* the preferred initial location to place the <code>Popup</code> at.
|
||||
* Based on screen size, or other paramaters, the <code>Popup</code> may
|
||||
* not display at <code>x</code> and <code>y</code>.
|
||||
*
|
||||
* @param owner Component mouse coordinates are relative to, may be null
|
||||
* @param contents Contents of the Popup
|
||||
* @param x Initial x screen coordinate
|
||||
* @param y Initial y screen coordinate
|
||||
*/
|
||||
public TranslucentPopup(Component owner, Component contents, int x,
|
||||
int y) {
|
||||
this();
|
||||
if (contents == null)
|
||||
throw new IllegalArgumentException("Contents must be non-null");
|
||||
|
||||
reset(owner, contents, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Popup</code>. This is provided for subclasses.
|
||||
*/
|
||||
public TranslucentPopup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Makes the <code>Popup</code> visible. If the <code>Popup</code> is
|
||||
* currently visible, this has no effect.<br>
|
||||
*
|
||||
* 本方法的结构完全copy自父类方法,但添加了component.repaint();的调用.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void show() {
|
||||
Component c = getComponent();
|
||||
|
||||
if (c != null) {
|
||||
c.setVisible(true);
|
||||
|
||||
//此行代码必须要有,否则可能是因为没有关闭双缓存(getRootPane().
|
||||
//setUseTrueDoubleBuffering(false),这个方法是包内可见,所以本类里没法调用
|
||||
//),而导致界面没有重绘:要不就是UI没有绘出来,要不就是出现空白的popup(没有内容组件)
|
||||
c.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides and disposes of the <code>Popup</code>. Once a
|
||||
* <code>Popup</code> has been disposed you should no longer invoke
|
||||
* methods on it. A <code>dispose</code>d <code>Popup</code> may be
|
||||
* reclaimed and later used based on the <code>PopupFactory</code>. As
|
||||
* such, if you invoke methods on a <code>disposed</code>
|
||||
* <code>Popup</code>, indeterminate behavior will result.
|
||||
*/
|
||||
@Override
|
||||
public void hide() {
|
||||
Component c = getComponent();
|
||||
|
||||
if (c instanceof JWindow) {
|
||||
c.hide();
|
||||
((JWindow) c).getContentPane().removeAll();
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees any resources the <code>Popup</code> may be holding onto.
|
||||
*/
|
||||
protected void dispose() {
|
||||
Component c = getComponent();
|
||||
Window window = SwingUtilities.getWindowAncestor(c);
|
||||
|
||||
if (c instanceof JWindow) {
|
||||
((Window) c).dispose();
|
||||
c = null;
|
||||
}
|
||||
// If our parent is a DefaultFrame, we need to dispose it, too.
|
||||
if (window instanceof DefaultFrame)
|
||||
window.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Resets the <code>Popup</code> to an initial state.<br>
|
||||
*
|
||||
* 本方法的结构完全copy自父类方法,但进行中包括:窗口透明、用图片实现背景填充等在内的修改.
|
||||
* </p>
|
||||
*
|
||||
* @param owner the owner
|
||||
* @param contents the contents
|
||||
* @param ownerX the owner x
|
||||
* @param ownerY the owner y
|
||||
*/
|
||||
protected void reset(Component owner, Component contents, int ownerX, int ownerY) {
|
||||
if (getComponent() == null)
|
||||
component = createComponent(owner);
|
||||
|
||||
Component c = getComponent();
|
||||
if (c instanceof JWindow) {
|
||||
JWindow w = (JWindow) getComponent();
|
||||
w.setLocation(ownerX, ownerY);
|
||||
|
||||
boolean isTooltip = ((JComponent) contents instanceof JToolTip);
|
||||
//如果contents是BasicComboPopup或其子类那当前就应该是用于下拉框的弹出列表罗
|
||||
boolean isComboBoxPopup = (contents instanceof BasicComboPopup);
|
||||
|
||||
//每像素透明
|
||||
WindowTranslucencyHelper.setWindowOpaque(w, false);
|
||||
//内容组件半透明
|
||||
w.setOpacity(isTooltip ? 1.0f : isComboBoxPopup ? 0.95f : 0.95f);//0.85f : 0.95f);//0.8f : 0.95f);
|
||||
|
||||
// component.getContentPane().add(contents, BorderLayout.CENTER);
|
||||
// contents.invalidate();
|
||||
// if (component.isVisible())
|
||||
// {
|
||||
// // Do not call pack() if window is not visible to
|
||||
// // avoid early native peer creation
|
||||
// pack();
|
||||
// }
|
||||
//图片填充背景的内容面板
|
||||
ImageBgPanel imageContentPane = new ImageBgPanel().setN9(
|
||||
isTooltip
|
||||
? ICON_9.get("tooltip")
|
||||
: isComboBoxPopup
|
||||
?//是下拉框列表则使一个跟JScrollPane一样的背景图,好看!
|
||||
BEScrollBarUI.ICON_9.get("scroll_pane_border")
|
||||
: ICON_9.get("popup")
|
||||
);
|
||||
imageContentPane.setLayout(new BorderLayout());
|
||||
imageContentPane.add(contents, BorderLayout.CENTER);
|
||||
|
||||
//为每一个要显示的真正的内容组件加一个空border,目的
|
||||
//是使得父面板的背景图片显示的效果更好
|
||||
if (contents instanceof JComponent) {
|
||||
((JComponent) contents).setOpaque(false);
|
||||
//* ######################################### Bug FIX START ############################################
|
||||
//* 关于Java Bug 6683775,地址:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6683775,解决于java1.6.0_14
|
||||
//*
|
||||
//* 【Bug说明】:
|
||||
//* 在java1.6.0_14之前(当然是>=u10版),在设置窗口透明时,即调用方法
|
||||
//* AWTUtilities.setWindowOpaque(component, false)使得窗口透明后,再设置位于
|
||||
//* Windows上的第1层JPanel也为透明时(即JPanel.setOpaque(false)),则会出现类似
|
||||
//* 于很久以前给JPanel设置一个半透明色(即alpha小于255)时出现的不正确paint情况,
|
||||
//* 直接导致下拉框的弹出列表ui刷新出现混乱(根本就不能即时刷新,ui一塌糊涂)的情况.
|
||||
//*
|
||||
//* 【java1.6.0_14版前如何解决】:
|
||||
//* 该Bug 6683775在被官方解决前,怎么才能避免出现ui刷新
|
||||
//* 混乱呢?Bug 6683775上的官方回复给出了解决方案:JPanel.setDoubleBuffered(false)(官方认为
|
||||
//* 光设置JPanel.setOpaque(false)是不够的,还得取消双缓冲才行),不过好在官方在u14及以后的版本中
|
||||
//* 彻底解决了这个问题.
|
||||
//*
|
||||
//* 【目前BeautyEye L&F中如何解决?】:
|
||||
//* 为了能在该Bug被解决前(即java小于java1.6.0_14版)BE LNF也能正常运行,只能稍微牺牲一点ui性能,
|
||||
//* 按官方解决方法——“JPanel.setDoubleBuffered(false)”来解决吧.
|
||||
((JComponent) contents).setDoubleBuffered(false);
|
||||
//* ######################################### Bug FIX END ##############################################
|
||||
|
||||
((JComponent) contents).setBorder(
|
||||
isTooltip
|
||||
? BorderFactory.createEmptyBorder(6, 8, 12, 12)//6,8,12,8)
|
||||
: isComboBoxPopup ? BorderFactory.createEmptyBorder(6, 4, 6, 4)
|
||||
: BorderFactory.createEmptyBorder(5, 3, 6, 3));//10,2,10,4));//5,5,20,5));
|
||||
}
|
||||
|
||||
//如果BasicComboPopup即表明它应该是ComboBox里的弹出菜单,为了使N9
|
||||
//背景能被完整展现出来则要把combox弹出列表所在的JScrollPane进行透明设置
|
||||
//,因为如果它不被透明设置则本pop的NP图背景就只能显示边缘,而且底边有一点被
|
||||
//挡住,不好看(另注:本JScrollPane在BEComboBoxUI中被设置了一个EmptyBorder,所以
|
||||
//没有在ScrollPaneUI中定认的那个ScrollBorder哦,没有那个border的目的就是为了在些使用
|
||||
//pop的背景撒)
|
||||
if (isComboBoxPopup) {
|
||||
Component[] cs = ((BasicComboPopup) contents).getComponents();
|
||||
//该JScrollPane就是contents的第一层子组件里
|
||||
if (cs != null && cs.length > 0)
|
||||
//遍历并找出它
|
||||
for (Component com : cs)
|
||||
if (com instanceof JScrollPane)
|
||||
((JScrollPane) com).setOpaque(false);
|
||||
} //如果是菜单父宿主则所有JMenuItem也设置透明,jb2011 2009-08-29
|
||||
else if (contents instanceof JPopupMenu) {
|
||||
MenuElement[] mes = ((JPopupMenu) contents).getSubElements();
|
||||
for (MenuElement me : mes)
|
||||
if (me instanceof JMenuItem)
|
||||
((JMenuItem) me).setOpaque(false);
|
||||
}
|
||||
|
||||
// add the contents to the popup
|
||||
w.setContentPane(imageContentPane);
|
||||
// popupWindow.getContentPane().add(p, BorderLayout.CENTER);
|
||||
// contents.invalidate();
|
||||
if (w.isVisible())
|
||||
// Do not call pack() if window is not visible to
|
||||
// avoid early native peer creation
|
||||
pack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the <code>Popup</code> to be sized to fit the preferred size
|
||||
* of the <code>Component</code> it contains.
|
||||
*/
|
||||
protected void pack() {
|
||||
Component c = getComponent();
|
||||
|
||||
if (c instanceof Window)
|
||||
((Window) c).pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Window</code> to use as the parent of the
|
||||
* <code>Window</code> created for the <code>Popup</code>. This creates
|
||||
* a new <code>DefaultFrame</code>, if necessary.
|
||||
*
|
||||
* @param owner the owner
|
||||
* @return the parent window
|
||||
*/
|
||||
protected Window getParentWindow(Component owner) {
|
||||
Window window = null;
|
||||
|
||||
if (owner instanceof Window)
|
||||
window = (Window) owner;
|
||||
else if (owner != null)
|
||||
window = SwingUtilities.getWindowAncestor(owner);
|
||||
if (window == null)
|
||||
window = new DefaultFrame();
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Component to use as the parent of the <code>Popup</code>.
|
||||
* The default implementation creates a <code>Window</code>, subclasses
|
||||
* should override.
|
||||
*
|
||||
* @param owner the owner
|
||||
* @return the component
|
||||
*/
|
||||
protected Component createComponent(Component owner) {
|
||||
if (GraphicsEnvironment.isHeadless())
|
||||
// Generally not useful, bail.
|
||||
return null;
|
||||
|
||||
return new HeavyWeightWindow(getParentWindow(owner));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Component</code> returned from
|
||||
* <code>createComponent</code> that will hold the <code>Popup</code>.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
protected Component getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used if no valid Window ancestor of the supplied owner is found.
|
||||
* <p>
|
||||
* PopupFactory uses this as a way to know when the Popup shouldn't be
|
||||
* cached based on the Window.
|
||||
*/
|
||||
protected class DefaultFrame extends Frame {
|
||||
}
|
||||
|
||||
/**
|
||||
* Component used to house window.
|
||||
*/
|
||||
protected class HeavyWeightWindow extends JWindow {
|
||||
|
||||
/**
|
||||
* Instantiates a new heavy weight window.
|
||||
*
|
||||
* @param parent the parent
|
||||
*/
|
||||
public HeavyWeightWindow(Window parent) {
|
||||
super(parent);
|
||||
// FIXME: 一个外国朋友用了后,在此项被设置成false的情况下,Popup里的JTextField不能编辑了!
|
||||
setFocusableWindowState(true);
|
||||
setName("###overrideRedirect###");
|
||||
// Popups are typically transient and most likely won't benefit
|
||||
// from true double buffering. Turn it off here.
|
||||
// getRootPane().setUseTrueDoubleBuffering(false);//本方法不能在包外被调用
|
||||
// Try to set "always-on-top" for the popup window.
|
||||
// Applets usually don't have sufficient permissions to do it.
|
||||
// In this case simply ignore the exception.
|
||||
try {
|
||||
setAlwaysOnTop(true);
|
||||
} catch (SecurityException se) {
|
||||
// setAlwaysOnTop is restricted,
|
||||
// the exception is ignored
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
this.pack();
|
||||
super.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.popup;
|
||||
|
||||
import javax.swing.PopupFactory;
|
||||
|
||||
public class __UI__ {
|
||||
|
||||
public static PopupFactory popupFactoryDIY = new TranslucentPopupFactory();
|
||||
|
||||
public static void uiImpl() {
|
||||
PopupFactory.setSharedInstance(popupFactoryDIY);
|
||||
}
|
||||
}
|
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEProgressBarUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.progress;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.AffineTransform;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.utils.MySwingUtilities2;
|
||||
import org.jackhuang.hmcl.laf.utils.WinUtils;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 进度条的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsProgressBarUI
|
||||
*/
|
||||
public class BEProgressBarUI extends BasicProgressBarUI
|
||||
implements org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("progress_bar");
|
||||
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new BEProgressBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,进度条和背景都是使用N9图,没法通过设置JProgressBar的背景色和前景
|
||||
* 色来控制进度条的颜色,本方法的目的就是当用户设置了进度条的Background或Foreground 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JProgressBar.setUI(new MetalProgressBar())方式来自定义进度的UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return progressBar != null
|
||||
&& (!(progressBar.getForeground() instanceof UIResource)
|
||||
|| !(progressBar.getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制普通进度条的方法.
|
||||
* All purpose paint method that should do the right thing for almost all
|
||||
* linear, determinate progress bars. By setting a few values in the
|
||||
* defaults table, things should work just fine to paint your progress bar.
|
||||
* Naturally, override this if you are making a circular or semi-circular
|
||||
* progress bar.
|
||||
*
|
||||
* @param g the g
|
||||
* @param c the c
|
||||
* @see #paintIndeterminate
|
||||
* @see javax.swing.plaf.basic.BasicProgressBarUI#paintDeterminate(java.awt.Graphics, javax.swing.JComponent)
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
protected void paintDeterminate(Graphics g, JComponent c) {
|
||||
if (!(g instanceof Graphics2D))
|
||||
return;
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (isUseParentPaint()) {
|
||||
super.paintDeterminate(g, c);
|
||||
return;
|
||||
}
|
||||
|
||||
Insets b = progressBar.getInsets(); // area for border
|
||||
int barRectWidth = progressBar.getWidth() - (b.right + b.left);
|
||||
int barRectHeight = progressBar.getHeight() - (b.top + b.bottom);
|
||||
|
||||
//* add by Jack Jiang 2012-06-20 START
|
||||
//绘制进度条的背景
|
||||
paintProgressBarBgImpl(progressBar.getOrientation() == JProgressBar.HORIZONTAL,
|
||||
g, b, barRectWidth, barRectHeight);
|
||||
//* add by Jack Jiang 2012-06-20 END
|
||||
|
||||
if (barRectWidth <= 0 || barRectHeight <= 0)
|
||||
return;
|
||||
|
||||
int amountFull = getAmountFull(b, barRectWidth, barRectHeight);
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setColor(progressBar.getForeground());//在BE LNF中本属性设置目前没有意义哦,因为用的都是n9图
|
||||
|
||||
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
|
||||
if (WinUtils.isLeftToRight(c))
|
||||
paintProgressBarContentImpl(true, g, b.left, b.top,
|
||||
amountFull, barRectHeight, -1);
|
||||
// TODO 以下代码未经测试
|
||||
else
|
||||
paintProgressBarContentImpl(true, g, barRectWidth + b.left, b.top,
|
||||
barRectWidth + b.left - amountFull, barRectHeight, -1);
|
||||
else // VERTICAL
|
||||
paintProgressBarContentImpl(false, g, b.left, b.top + barRectHeight - amountFull,
|
||||
barRectWidth, amountFull, barRectHeight);
|
||||
|
||||
// Deal with possible text painting
|
||||
if (progressBar.isStringPainted())
|
||||
paintString(g, b.left, b.top, barRectWidth, barRectHeight, amountFull, b);
|
||||
}
|
||||
|
||||
//绘制无穷进度条的方法
|
||||
/**
|
||||
* All purpose paint method that should do the right thing for all linear
|
||||
* bouncing-box progress bars. Override this if you are making another kind
|
||||
* of progress bar.
|
||||
*
|
||||
* @param g the g
|
||||
* @param c the c
|
||||
* @see #paintDeterminate
|
||||
* @since 1.4
|
||||
* @see javax.swing.plaf.basic.BasicProgressBarUI#paintIndeterminate(java.awt.Graphics, javax.swing.JComponent)
|
||||
*/
|
||||
@Override
|
||||
protected void paintIndeterminate(Graphics g, JComponent c) {
|
||||
if (!(g instanceof Graphics2D))
|
||||
return;
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (isUseParentPaint()) {
|
||||
super.paintIndeterminate(g, c);
|
||||
return;
|
||||
}
|
||||
|
||||
Insets b = progressBar.getInsets(); // area for border
|
||||
int barRectWidth = progressBar.getWidth() - (b.right + b.left);
|
||||
int barRectHeight = progressBar.getHeight() - (b.top + b.bottom);
|
||||
|
||||
if (barRectWidth <= 0 || barRectHeight <= 0)
|
||||
return;
|
||||
|
||||
//* add by Jack Jiang 2012-06-20 START
|
||||
//绘制进度条的背景
|
||||
paintProgressBarBgImpl(progressBar.getOrientation() == JProgressBar.HORIZONTAL, g, b, barRectWidth, barRectHeight);
|
||||
//* add by Jack Jiang 2012-06-20 END
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
// Paint the bouncing box.
|
||||
boxRect = getBox(boxRect);
|
||||
if (boxRect != null) {
|
||||
g2.setColor(progressBar.getForeground());//BE LNF中,目前本颜色设置无意义哦,因使用的都是N9图
|
||||
//由Jack Jiang修改
|
||||
// g2.fillRect(boxRect.x, boxRect.y, boxRect.width, boxRect.height);
|
||||
paintProgressBarContentImpl(progressBar.getOrientation() == JProgressBar.HORIZONTAL,
|
||||
g, boxRect.x, boxRect.y, boxRect.width, boxRect.height, boxRect.height);//水平时最后一个参数无意义哦
|
||||
}
|
||||
|
||||
// Deal with possible text painting
|
||||
if (progressBar.isStringPainted())
|
||||
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
|
||||
paintString(g2, b.left, b.top, barRectWidth, barRectHeight, boxRect.x, boxRect.width, b);
|
||||
else
|
||||
paintString(g2, b.left, b.top, barRectWidth, barRectHeight, boxRect.y, boxRect.height, b);
|
||||
}
|
||||
|
||||
//* add by Jack Jiang
|
||||
/**
|
||||
* 进度条当前值的绘制实现方法.
|
||||
*
|
||||
* @param isHorizontal true表示水平进度条,否则表示垂直进度条
|
||||
* @param g the g
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param amountFull the amount full
|
||||
* @param barContentRectHeight the bar content rect height
|
||||
* @param barSumHeightForVertival 本参数只在垂直进度条时有意义,目的是为了在当前值很
|
||||
* 小的情况下为了达到N9图最小绘制高度时,作修正时需要
|
||||
*/
|
||||
protected void paintProgressBarContentImpl(boolean isHorizontal,
|
||||
Graphics g, int x, int y, int amountFull, int barContentRectHeight,
|
||||
int barSumHeightForVertival) {
|
||||
NinePatch np;
|
||||
|
||||
//当前的进度条内容.9.png图片的边缘非填充部分是17像素,如果要
|
||||
//填充的总宽度小于此则会出现NinePatch填充算法无法解决的填充,
|
||||
//以下判断将在总宽度小于此值时强制设置成最小宽度
|
||||
final int n9min = 17;// TODO 14是相关于.9.png图片的最小填充宽度的,最好用常量实现
|
||||
if (isHorizontal) {
|
||||
//如果最小填充长度小于n9图的最小长度最设定为最小长度,否则N9的填充会很难看哦
|
||||
if (amountFull > 0 && amountFull < n9min)
|
||||
amountFull = n9min;
|
||||
np = ICON_9.get("green");
|
||||
} else {
|
||||
//如果最小填充长度小于n9图的最小长度最设定为最小长度,否则N9的填充会很难看哦
|
||||
if (barContentRectHeight > 0 && barContentRectHeight < n9min) {
|
||||
y = barSumHeightForVertival - n9min;
|
||||
barContentRectHeight = n9min;
|
||||
}
|
||||
np = ICON_9.get("blur_vertical");
|
||||
}
|
||||
//开始绘制N9图
|
||||
np.draw((Graphics2D) g, x, y, amountFull, barContentRectHeight);
|
||||
}
|
||||
|
||||
//* add by Jack Jiang
|
||||
/**
|
||||
* 进度条背景填充实现方法.
|
||||
*
|
||||
* @param isHorizontal the is horizontal
|
||||
* @param g the g
|
||||
* @param b the b
|
||||
* @param barRectWidth the bar rect width
|
||||
* @param barRectHeight the bar rect height
|
||||
*/
|
||||
protected void paintProgressBarBgImpl(boolean isHorizontal, Graphics g, Insets b, int barRectWidth, int barRectHeight) {
|
||||
ICON_9.getWithHorizontal("bg", isHorizontal)
|
||||
.draw((Graphics2D) g, b.left, b.top, barRectWidth, barRectHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the progress string.
|
||||
*
|
||||
* @param g Graphics used for drawing.
|
||||
* @param x x location of bounding box
|
||||
* @param y y location of bounding box
|
||||
* @param width width of bounding box
|
||||
* @param height height of bounding box
|
||||
* @param fillStart start location, in x or y depending on orientation, of
|
||||
* the filled portion of the progress bar.
|
||||
* @param amountFull size of the fill region, either width or height
|
||||
* depending upon orientation.
|
||||
* @param b Insets of the progress bar.
|
||||
*/
|
||||
private void paintString(Graphics g, int x, int y, int width, int height,
|
||||
int fillStart, int amountFull, Insets b) {
|
||||
if (!(g instanceof Graphics2D))
|
||||
return;
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
String progressString = progressBar.getString();
|
||||
g2.setFont(progressBar.getFont());
|
||||
Point renderLocation = getStringPlacement(g2, progressString,
|
||||
x, y, width, height);
|
||||
Rectangle oldClip = g2.getClipBounds();
|
||||
|
||||
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
|
||||
g2.setColor(getSelectionBackground());
|
||||
MySwingUtilities2.drawString(progressBar, g2, progressString,
|
||||
renderLocation.x, renderLocation.y);
|
||||
g2.setColor(getSelectionForeground());
|
||||
g2.clipRect(fillStart, y, amountFull, height);
|
||||
MySwingUtilities2.drawString(progressBar, g2, progressString,
|
||||
renderLocation.x, renderLocation.y);
|
||||
} else { // VERTICAL
|
||||
g2.setColor(getSelectionBackground());
|
||||
AffineTransform rotate
|
||||
= AffineTransform.getRotateInstance(Math.PI / 2);
|
||||
g2.setFont(progressBar.getFont().deriveFont(rotate));
|
||||
renderLocation = getStringPlacement(g2, progressString,
|
||||
x, y, width, height);
|
||||
MySwingUtilities2.drawString(progressBar, g2, progressString,
|
||||
renderLocation.x, renderLocation.y);
|
||||
g2.setColor(getSelectionForeground());
|
||||
g2.clipRect(x, fillStart, width, amountFull);
|
||||
MySwingUtilities2.drawString(progressBar, g2, progressString,
|
||||
renderLocation.x, renderLocation.y);
|
||||
}
|
||||
g2.setClip(oldClip);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.progress;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
put("ProgressBar.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("ProgressBar.selectionForeground", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
|
||||
// 此属性决定水平进度条的默认最小大小:15是相关于.9.png图片的最小填充
|
||||
// 高度或长度的(小于此高度则NinePatch算法无法解决而很难看)
|
||||
putDim("ProgressBar.horizontalSize", 146, 15); // 默认是146,12
|
||||
putDim("ProgressBar.verticalSize", 15, 146); // 默认是12,146
|
||||
put("ProgressBar.border", BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
||||
put("ProgressBarUI", BEProgressBarUI.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.radio$cb_btn;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.metal.MetalCheckBoxUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class BECheckBoxUI extends MetalCheckBoxUI {
|
||||
|
||||
private static final BECheckBoxUI INSTANCE = new BECheckBoxUI();
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
|
||||
LookAndFeel.installProperty(b, "opaque", false);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.radio$cb_btn;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.metal.MetalRadioButtonUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class BERadioButtonUI extends MetalRadioButtonUI {
|
||||
|
||||
private static final BERadioButtonUI INSTANCE = new BERadioButtonUI();
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installDefaults(AbstractButton b) {
|
||||
super.installDefaults(b);
|
||||
|
||||
LookAndFeel.installProperty(b, "opaque", false);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.radio$cb_btn;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
private static final IconFactory RADIO = new IconFactory("radio");
|
||||
private static final IconFactory CHECK = new IconFactory("check");
|
||||
|
||||
public static void uiImpl() {
|
||||
|
||||
putInsets("CheckBox.margin", 4, 3, 4, 3);
|
||||
put("CheckBox.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("CheckBox.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("CheckBoxUI", BECheckBoxUI.class);
|
||||
|
||||
putInsets("RadioButton.margin", 4, 3, 4, 3); // 2, 2, 2, 2
|
||||
put("RadioButton.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("RadioButton.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("RadioButtonUI", BERadioButtonUI.class);
|
||||
|
||||
UIManager.put("RadioButton.icon", new IconFactoryIcon(RADIO));
|
||||
UIManager.put("CheckBox.icon", new IconFactoryIcon(CHECK));
|
||||
|
||||
// 衬距设定
|
||||
putInsets("RadioButton.margin", 1, 1, 1, 1); // 2, 2, 2, 2
|
||||
putInsets("CheckBox.margin", 1, 1, 1, 1); // 2, 2, 2, 2
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsIconFactory
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsIconFactory.CheckBoxIcon
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsIconFactory.RadioBoxIcon
|
||||
*/
|
||||
private static class IconFactoryIcon implements Icon, Serializable {
|
||||
IconFactory icon;
|
||||
|
||||
public IconFactoryIcon(IconFactory icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
JToggleButton cb = (JToggleButton) c;
|
||||
ButtonModel model = cb.getModel();
|
||||
|
||||
g.drawImage(icon.get(model.isSelected() ? "" : "unchecked",
|
||||
model.isEnabled() ? (model.isPressed() ? "pressed" : (model.isRollover() ? "over" : "normal")) : "disabled").getImage(),
|
||||
x, y, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return 24;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return 24;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* beautyeye.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class beautyeye extends ListResourceBundle
|
||||
{
|
||||
protected final Object[][] getContents()
|
||||
{
|
||||
return new Object[][] {
|
||||
{ "BETitlePane.setupButtonText", "Setup " },
|
||||
{ "BETitlePane.titleMenuToolTipText", "Window operation." },
|
||||
{ "BETitlePane.closeButtonToolTipext", "Close" },
|
||||
{ "BETitlePane.iconifyButtonToolTipText", "Minimize" },
|
||||
{ "BETitlePane.toggleButtonToolTipText", "Maximize" },
|
||||
{ "BETitlePane.iconifyButtonText", "Minimize(N)" },
|
||||
{ "BETitlePane.restoreButtonText", "Restore(R)" },
|
||||
{ "BETitlePane.maximizeButtonText", "Maximized(X)" },
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* beautyeye_zh_CN.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class beautyeye_zh_CN extends ListResourceBundle
|
||||
{
|
||||
protected final Object[][] getContents()
|
||||
{
|
||||
return new Object[][] {
|
||||
{ "BETitlePane.setupButtonText", "\u8bbe\u7f6e " },
|
||||
{ "BETitlePane.titleMenuToolTipText", "\u7a97\u53e3\u76f8\u5173\u64cd\u4f5c." },
|
||||
{ "BETitlePane.closeButtonToolTipext", "\u5173\u95ed" },
|
||||
{ "BETitlePane.iconifyButtonToolTipText", "\u6700\u5c0f\u5316" },
|
||||
{ "BETitlePane.toggleButtonToolTipText", "\u6700\u5927\u5316" },
|
||||
{ "BETitlePane.iconifyButtonText", "\u6700\u5c0f\u5316(N)" },
|
||||
{ "BETitlePane.restoreButtonText", "\u8fd8\u539f(R)" },
|
||||
{ "BETitlePane.maximizeButtonText", "\u6700\u5927\u5316(X)" },
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEScrollBarUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.scroll;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicArrowButton;
|
||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 本类是滚动条的UI实现.
|
||||
*
|
||||
* 注:滚动条的两端箭头按钮参考自xp主题的实现,未作修改,因而这部分逻辑代码与WindowsScrollBarUI中是完全一样的.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2009-09-01
|
||||
* @version 1.0
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsScrollBarUI
|
||||
*/
|
||||
public class BEScrollBarUI extends BasicScrollBarUI {
|
||||
|
||||
public static final Icon9Factory ICON_9 = new Icon9Factory("scroll_bar");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEScrollBarUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JButton createDecreaseButton(int orientation) {
|
||||
return new BEArrowButton(orientation,
|
||||
UIManager.getColor("ScrollBar.thumb"),
|
||||
UIManager.getColor("ScrollBar.thumbShadow"),
|
||||
UIManager.getColor("ScrollBar.thumbDarkShadow"),
|
||||
UIManager.getColor("ScrollBar.thumbHighlight"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JButton createIncreaseButton(int orientation) {
|
||||
return new BEArrowButton(orientation,
|
||||
UIManager.getColor("ScrollBar.thumb"),
|
||||
UIManager.getColor("ScrollBar.thumbShadow"),
|
||||
UIManager.getColor("ScrollBar.thumbDarkShadow"),
|
||||
UIManager.getColor("ScrollBar.thumbHighlight"));
|
||||
}
|
||||
|
||||
/**
|
||||
* WindowsArrowButton is used for the buttons to position the document
|
||||
* up/down. It differs from BasicArrowButton in that the preferred size is
|
||||
* always a square.
|
||||
*/
|
||||
protected class BEArrowButton extends BasicArrowButton {
|
||||
|
||||
/**
|
||||
* Instantiates a new windows arrow button.
|
||||
*
|
||||
* @param direction the direction
|
||||
* @param background the background
|
||||
* @param shadow the shadow
|
||||
* @param darkShadow the dark shadow
|
||||
* @param highlight the highlight
|
||||
*/
|
||||
public BEArrowButton(int direction, Color background, Color shadow,
|
||||
Color darkShadow, Color highlight) {
|
||||
super(direction, background, shadow, darkShadow, highlight);
|
||||
}
|
||||
|
||||
public BEArrowButton(int direction) {
|
||||
super(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
String id = "arrow_";
|
||||
switch (direction) {
|
||||
case NORTH:
|
||||
id += "top";
|
||||
break;
|
||||
case SOUTH:
|
||||
id += "bottom";
|
||||
break;
|
||||
case WEST:
|
||||
id += "left";
|
||||
break;
|
||||
case EAST:
|
||||
id += "right";
|
||||
break;
|
||||
}
|
||||
ICON_9.get(id, getModel().isRollover() ? "rollover" : "")
|
||||
.draw(g2, 0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
int size = 16;
|
||||
if (scrollbar != null) {
|
||||
switch (scrollbar.getOrientation()) {
|
||||
case JScrollBar.VERTICAL:
|
||||
size = scrollbar.getWidth();
|
||||
break;
|
||||
case JScrollBar.HORIZONTAL:
|
||||
size = scrollbar.getHeight();
|
||||
break;
|
||||
}
|
||||
size = Math.max(size, 5);
|
||||
}
|
||||
return new Dimension(size, size);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------- END
|
||||
|
||||
//----------------------------------------------------------------------------------- 本次改造的主体部分
|
||||
@Override
|
||||
protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {
|
||||
if (c == null || g == null)
|
||||
return;
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
Paint oldp = g2.getPaint();
|
||||
int w = trackBounds.width;
|
||||
int h = trackBounds.height;
|
||||
int x = trackBounds.x;
|
||||
int y = trackBounds.y;
|
||||
|
||||
if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {
|
||||
// //1/2处渐变
|
||||
// GradientPaint gp = new GradientPaint(x, y
|
||||
// , GraphicHandler.getColor(trackColor,-15,-15,-15), w/2, y,trackColor);
|
||||
// g2.setPaint(gp);
|
||||
// g2.fillRect(x, y, w/2, h);
|
||||
//
|
||||
// g2.setPaint(oldp);
|
||||
// g2.setColor(trackColor);
|
||||
// g2.fillRect(w/2, y, w/2, h);
|
||||
|
||||
//** 简洁版轨迹实现
|
||||
int hhhWidth = 5;
|
||||
int px = (w - hhhWidth) / 2;
|
||||
int delta = 50;
|
||||
//第1条
|
||||
g2.setColor(new Color(150 + delta, 151 + delta, 146 + delta));
|
||||
g2.drawLine(px + 0, y + 10, px + 0, y + h - 10);
|
||||
//第2条
|
||||
g2.setColor(new Color(160 + delta, 160 + delta, 162 + delta));
|
||||
g2.drawLine(px + 1, y + 10, px + 1, y + h - 10);
|
||||
//第3条
|
||||
g2.setColor(new Color(163 + delta, 162 + delta, 167 + delta));
|
||||
g2.drawLine(px + 2, y + 10, px + 2, y + h - 10);
|
||||
//第4条
|
||||
g2.setColor(new Color(162 + delta, 162 + delta, 162 + delta));
|
||||
g2.drawLine(px + 3, y + 10, px + 3, y + h - 10);
|
||||
//第5条
|
||||
g2.setColor(new Color(150 + delta, 150 + delta, 150 + delta));
|
||||
g2.drawLine(px + 4, y + 10, px + 4, y + h - 10);
|
||||
} else {
|
||||
//1/2处渐变
|
||||
// GradientPaint gp = new GradientPaint(x, y
|
||||
// , GraphicHandler.getColor(trackColor,-15,-15,-15), x, h/2,trackColor);
|
||||
// g2.setPaint(gp);
|
||||
// g2.fillRect(x, y, w, h/2);
|
||||
//
|
||||
// g2.setPaint(oldp);
|
||||
// g2.setColor(trackColor);
|
||||
// g2.fillRect(x, h/2, w, h);
|
||||
|
||||
//** 简洁版轨迹实现
|
||||
int hhhWidth = 5;
|
||||
int py = (h - hhhWidth) / 2;
|
||||
int delta = 50;
|
||||
//第1条
|
||||
g2.setColor(new Color(150 + delta, 151 + delta, 146 + delta));
|
||||
g2.drawLine(x + 10, py + 0, x + w - 10, py + 0);
|
||||
//第2条
|
||||
g2.setColor(new Color(160 + delta, 160 + delta, 162 + delta));
|
||||
g2.drawLine(x + 10, py + 1, x + w - 10, py + 1);
|
||||
//第3条
|
||||
g2.setColor(new Color(163 + delta, 162 + delta, 167 + delta));
|
||||
g2.drawLine(x + 10, py + 2, x + w - 10, py + 2);
|
||||
//第4条
|
||||
g2.setColor(new Color(162 + delta, 162 + delta, 162 + delta));
|
||||
g2.drawLine(x + 10, py + 3, x + w - 10, py + 3);
|
||||
//第5条
|
||||
g2.setColor(new Color(150 + delta, 150 + delta, 150 + delta));
|
||||
g2.drawLine(x + 10, py + 4, x + w - 10, py + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动条绘制.
|
||||
*/
|
||||
@Override
|
||||
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
|
||||
if (thumbBounds.isEmpty() || !scrollbar.isEnabled())
|
||||
return;
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
int w = thumbBounds.width - 4;
|
||||
int h = thumbBounds.height - 4;
|
||||
g2.translate(thumbBounds.x + 2, thumbBounds.y + 2);
|
||||
|
||||
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
BEUtils.setAntiAliasing(g2, true);
|
||||
|
||||
//防止thunmb的最小高度比图片的最小高度还要小,这样在绘制时就会出问题
|
||||
//起实,目前没还没有办法很好解决,因为即使在这里作处理,但是thumb本身
|
||||
//还是那么小,所以绘图还是会有问题,但起码在不拖动时看起来是正常的,以后再解决吧!
|
||||
if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {
|
||||
NinePatch np = ICON_9.getWithScrollState("vertical", isDragging, isThumbRollover());
|
||||
if (h < np.getHeight())
|
||||
paintThumbIfSoSmall(g2, 0, 0, w, h);
|
||||
else
|
||||
np.draw(g2, 0, 0, w, h);
|
||||
} else {
|
||||
NinePatch np = ICON_9.getWithScrollState("horizontal", isDragging, isThumbRollover());
|
||||
|
||||
if (w < np.getWidth())
|
||||
paintThumbIfSoSmall(g2, 0, 0, w, h);
|
||||
else
|
||||
np.draw(g2, 0, 0, w, h);
|
||||
}
|
||||
//如果滚动行宽度小于NP图的最小宽度时则交给此方法绘制(否则NP图的填充将出现虚绘,而影响滚动条的体验哦)
|
||||
|
||||
g2.translate(-thumbBounds.x, -thumbBounds.y);
|
||||
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
BEUtils.setAntiAliasing(g2, false);
|
||||
}
|
||||
//----------------------------------------------------------------------------------- END
|
||||
|
||||
/**
|
||||
* 如果滚动条非常小(小到小于NP图的最小大小)时调用此方法实现滚动条的精确绘制.
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicScrollBarUI#paintThumb(java.awt.Graphics, javax.swing.JComponent, java.awt.Rectangle)
|
||||
*/
|
||||
protected void paintThumbIfSoSmall(Graphics2D g2, int x, int y, int w, int h) {
|
||||
final int NORMAL_ARC = 6;//定义圆角直径
|
||||
//如果w或h太小时,则就不绘制圆角了(直角即可),要不然就没法绘全圆角而很难看
|
||||
int arc = ((w <= NORMAL_ARC || h <= NORMAL_ARC) ? 0 : NORMAL_ARC);
|
||||
g2.setColor(thumbDarkShadowColor);
|
||||
g2.drawRoundRect(x, y, w - 1, h - 1, arc, arc);//画滚动条的外层
|
||||
g2.setColor(thumbColor);
|
||||
g2.fillRoundRect(x + 1, y + 1, w - 2, h - 2, arc, arc);//填充滚动条的内层
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEScrollPaneUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.scroll;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
||||
|
||||
/**
|
||||
* 滚动面板的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com
|
||||
*/
|
||||
public class BEScrollPaneUI extends BasicScrollPaneUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new BEScrollPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults(JScrollPane scrollpane) {
|
||||
super.installDefaults(scrollpane);
|
||||
|
||||
// /* ~~注:ScrollPane.opaque这个属性是jb2011自已加的,目的是控制滚动面板及其Viewport的透明性 */
|
||||
// scrollpane.setOpaque(UIManager.getBoolean("ScrollPane.opaque"));
|
||||
// scrollpane.getViewport().setOpaque(UIManager.getBoolean("ScrollPane.opaque"));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* ScrollPaneBorder.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.scroll;
|
||||
|
||||
import java.awt.Insets;
|
||||
|
||||
import org.jackhuang.hmcl.laf.widget.border.NinePatchBorder;
|
||||
|
||||
/**
|
||||
* 滚动面板默认Border的实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class ScrollPaneBorder extends NinePatchBorder {
|
||||
|
||||
public ScrollPaneBorder() {
|
||||
super(new Insets(6, 6, 8, 6),
|
||||
BEScrollBarUI.ICON_9.get("scroll_pane_border"));
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.scroll;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 视口的相关ui值设定
|
||||
put("Viewport.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("Viewport.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JScrollPane的相关ui值设定
|
||||
put("ScrollPane.border", new ScrollPaneBorder()); // 0, 0, 0, 0
|
||||
// 不能设置alpha通道小于255的透明颜色,否则会出现无法重paint的问题
|
||||
put("ScrollPane.background", Color.white);//cc));
|
||||
put("ScrollPane.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("ScrollPaneUI", BEScrollPaneUI.class);
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JScrollPane的滚动条相关ui值设定
|
||||
put("ScrollBar.thumb", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("ScrollBar.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
putColor("ScrollBar.background", 250, 250, 250);
|
||||
putColor("ScrollBar.trackForeground", 250, 250, 250);
|
||||
putColor("scrollbar", 250, 250, 250);
|
||||
put("ScrollBarUI", BEScrollBarUI.class);
|
||||
|
||||
// /* ~~注:这个属性是jb2011自已加的,目的是控制滚动面板及其Viewport的透明性 */
|
||||
// //设置成透明是为了让BE LNF中它的N9图实现的border能展现出图片背景来,好看一点
|
||||
// put("ScrollPane.opaque", false);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.separator;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.PanelUI;
|
||||
import javax.swing.plaf.basic.BasicPanelUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class BEPanelUI extends BasicPanelUI {
|
||||
|
||||
// Shared UI object
|
||||
private static PanelUI panelUI;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
if (panelUI == null)
|
||||
panelUI = new BEPanelUI();
|
||||
return panelUI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults(JPanel p) {
|
||||
LookAndFeel.installProperty(p, "opaque", false);
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BESeparatorUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.separator;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicSeparatorUI;
|
||||
|
||||
/**
|
||||
* Separator外观实现类.
|
||||
* <p>
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-11-05
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BESeparatorUI extends BasicSeparatorUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BESeparatorUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults(JSeparator s) {
|
||||
LookAndFeel.installColors(s, "Separator.background", "Separator.foreground");
|
||||
LookAndFeel.installProperty(s, "opaque", Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
//** 绘制border的底线
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);//
|
||||
// super.paint(g, c);
|
||||
|
||||
Dimension s = c.getSize();
|
||||
|
||||
if (((JSeparator) c).getOrientation() == JSeparator.VERTICAL) {
|
||||
// System.out.println("c.getBackground()c.getBackground()c.getBackground()="+c.getBackground());
|
||||
g.setColor(c.getForeground());
|
||||
g.drawLine(0, 0, 0, s.height);
|
||||
|
||||
g.setColor(c.getBackground());
|
||||
g.drawLine(1, 0, 1, s.height);
|
||||
} else // HORIZONTAL
|
||||
{
|
||||
g.setColor(c.getForeground());
|
||||
g.drawLine(0, 0, s.width, 0);
|
||||
|
||||
g.setColor(c.getBackground());
|
||||
g.drawLine(0, 1, s.width, 1);
|
||||
}
|
||||
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.separator;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
import org.jackhuang.hmcl.laf.widget.border.BEDashedRoundRecBorder;
|
||||
|
||||
/**
|
||||
* 各种未归类的UI属性设置实现类. 本类中的各种属性日后可能会移入相应的各独立组件的UI包.
|
||||
*
|
||||
* @author Jack Jiang
|
||||
* @version 1.1
|
||||
*/
|
||||
public class __UI__ extends UI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("option_pane");
|
||||
|
||||
public static void uiImpl() {
|
||||
put("control", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("Separator.foreground", new Color(180, 180, 180));
|
||||
put("ToolTip.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
put("Separator.background", Color.white);
|
||||
put("Panel.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("Panel.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("PanelUI", BEPanelUI.class);
|
||||
|
||||
put("Label.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
//put("Label.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
|
||||
put("ColorChooser.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("ColorChooser.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("ColorChooser.swatchesDefaultRecentColor", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
|
||||
putColor("TitledBorder.titleColor", 58, 135, 173); // TitleBorder的标题颜色
|
||||
// TitledBorder的默认border实现(windows LNF中默认是圆色灰色实线距形)
|
||||
put("TitledBorder.border", new BEDashedRoundRecBorder(BeautyEyeLNFHelper.commonFocusedBorderColor));
|
||||
|
||||
// UIManager.put("OptionPaneUI",org.jb2011.lnf.windows2.ch3.NLOptionPaneUI.class.getName());
|
||||
//** Ui里的实现逻辑:此属性为true时将导致JOptionPane里的各按钮按BasicOptionPaneUI里设定的Insets进行
|
||||
//** UI展现:当按钮数<=2时使用的Insets=new Instes(2,8,2,8),否则使用new Instes(2,4,2,4),
|
||||
//** 这样的逻辑下,BeautyEye L&F实现里会使得按钮高度缩小而不好看,所以要关闭此属性
|
||||
put("OptionPane.setButtonMargin", false);
|
||||
put("OptionPane.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("OptionPane.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
UIManager.put("OptionPane.questionIcon", ICON.get("question"));
|
||||
UIManager.put("OptionPane.warningIcon", ICON.get("warn"));
|
||||
UIManager.put("OptionPane.informationIcon", ICON.get("info"));
|
||||
UIManager.put("OptionPane.errorIcon", ICON.get("error"));
|
||||
|
||||
put("SeparatorUI", BESeparatorUI.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BESliderUI.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.slider;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicSliderUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
|
||||
/**
|
||||
* JSlider的ui实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
*
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsComboBoxUI
|
||||
*/
|
||||
public class BESliderUI extends BasicSliderUI {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("slider_track");
|
||||
private static final IconFactory ICON = new IconFactory("slider");
|
||||
|
||||
/**
|
||||
* 水平Slider的Thumb高度.
|
||||
*/
|
||||
protected final int THUMB_HEIGHT_HORIZONAL = 7;// TODO 此属性可提取为Ui属性,方便以后配置(大小应是NP图的最小高度,最大值得看JSlider的高度了)
|
||||
|
||||
/**
|
||||
* 垂直Slider的Thumb宽度.
|
||||
*/
|
||||
protected final int THUMB_WIDTH_VERTICAL = 7;// TODO 此属性可提取为Ui属性,方便以后配置(大小应是NP图的最小高度,最大值得看JSlider的高度了)
|
||||
|
||||
public BESliderUI(JSlider b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
public static ComponentUI createUI(JComponent b) {
|
||||
return new BESliderUI((JSlider) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintTrack(Graphics g) {
|
||||
Rectangle trackBounds = trackRect;
|
||||
if (slider.getOrientation() == JSlider.HORIZONTAL) {
|
||||
int cy = (trackBounds.height / 2) - 2;
|
||||
int cw = trackBounds.width;
|
||||
|
||||
g.translate(trackBounds.x, trackBounds.y + cy);
|
||||
|
||||
//轨道背景
|
||||
ICON_9.getWithEnabled("", slider.isEnabled())
|
||||
.draw((Graphics2D) g, 0, 0, cw, THUMB_HEIGHT_HORIZONAL);
|
||||
//轨道(填充到当前刻度值处)
|
||||
ICON_9.getWithEnabled("foreground", slider.isEnabled())
|
||||
.draw((Graphics2D) g, 0, 0, thumbRect.x, THUMB_HEIGHT_HORIZONAL);
|
||||
g.translate(-trackBounds.x, -(trackBounds.y + cy));
|
||||
} else {
|
||||
int cx = (trackBounds.width / 2) - 2;
|
||||
int ch = trackBounds.height;
|
||||
|
||||
g.translate(trackBounds.x + cx, trackBounds.y);
|
||||
|
||||
//轨道背景
|
||||
ICON_9.getWithEnabled("vertical", slider.isEnabled())
|
||||
.draw((Graphics2D) g, 0, 0, THUMB_WIDTH_VERTICAL, ch);
|
||||
//轨道(填充到当前刻度值处)
|
||||
// TODO BUG:当前有个bug,即在SwingSets2演示中,当thumb高度较小时,轨道半圆形被画出,这可能父类中thumbRect中计算有部碮同,有时间再研究吧,官方以后版本或许能解决哦
|
||||
ICON_9.getWithEnabled("vertical_foreground", slider.isEnabled())
|
||||
.draw((Graphics2D) g, 0, thumbRect.y, THUMB_WIDTH_VERTICAL, ch - thumbRect.y);
|
||||
|
||||
g.translate(-(trackBounds.x + cx), -trackBounds.y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintFocus(Graphics g) {
|
||||
g.setColor(getFocusColor());
|
||||
BEUtils.drawDashedRect(g, focusRect.x, focusRect.y,
|
||||
focusRect.width, focusRect.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicSliderUI#paintThumb(java.awt.Graphics)
|
||||
*/
|
||||
@Override
|
||||
public void paintThumb(Graphics g) {
|
||||
Rectangle knobBounds = thumbRect;
|
||||
int w = knobBounds.width;
|
||||
int h = knobBounds.height;
|
||||
|
||||
g.translate(knobBounds.x, knobBounds.y);
|
||||
if (slider.isEnabled())
|
||||
g.setColor(slider.getBackground());
|
||||
else
|
||||
g.setColor(slider.getBackground().darker());
|
||||
|
||||
g.drawImage(ICON.get(isPaintNoTriangleThumb() ? "notriangle" : "",
|
||||
slider.getOrientation() == JSlider.HORIZONTAL ? "" : "vertical",
|
||||
slider.isEnabled() ? "" : "disabled").getImage(), 0, 0, null);
|
||||
|
||||
g.translate(-knobBounds.x, -knobBounds.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is paint no triangle thumb.
|
||||
* 该thumb是否是无3角箭头的样式,true表示无3解箭头(即圆形thumb),false表示有3角箭头样式
|
||||
*
|
||||
* @return true, if is paint no trangle thumb
|
||||
*/
|
||||
protected boolean isPaintNoTriangleThumb() {
|
||||
Boolean paintThumbArrowShape = (Boolean) slider
|
||||
.getClientProperty("Slider.paintThumbArrowShape");
|
||||
|
||||
//不绘制有箭头标识的thumb样式(即普通圆形thumb)
|
||||
return !slider.getPaintTicks() && paintThumbArrowShape == null
|
||||
|| Boolean.FALSE.equals(paintThumbArrowShape);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicSliderUI#getThumbSize()
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getThumbSize() {
|
||||
boolean isPaintNoTrangle = isPaintNoTriangleThumb();
|
||||
|
||||
Dimension size = new Dimension();
|
||||
if (slider.getOrientation() == JSlider.VERTICAL) {
|
||||
size.width = 17;//20;
|
||||
size.height = isPaintNoTrangle ? 16 : 12;//14;
|
||||
} else {
|
||||
size.width = isPaintNoTrangle ? 16 : 12;//14;
|
||||
size.height = 17;//20;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.slider;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
put("Slider.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
//JSlider的刻度线绘制颜色
|
||||
putColor("Slider.tickColor", 154, 154, 154);
|
||||
put("Slider.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
//获得焦点时的insets
|
||||
// putInsets("Slider.focusInsets", 2, 2, 7, 7); //父类中默认是 2, 2, 2, 2
|
||||
//获得焦点时的焦点边框颜色
|
||||
put("Slider.focus", BeautyEyeLNFHelper.commonFocusedBorderColor); //[r=113,g=111,b=100]
|
||||
put("SliderUI", BESliderUI.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BESpinnerUI.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.spinner;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicSpinnerUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.spinner.BESpinnerUI.GlyphButton.Type;
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* JSPinner的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @version 1.0
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsSpinnerUI
|
||||
*/
|
||||
public class BESpinnerUI extends BasicSpinnerUI {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("spinner");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BESpinnerUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createEditor() {
|
||||
JComponent e = super.createEditor();
|
||||
e.setOpaque(false);
|
||||
|
||||
//参见JSpinner.NumberEditor,super.createEditor()返回值就是它的父类
|
||||
//(是一个JPanel实例),它是由一个FormatttedTextField及其父JPanel组成
|
||||
//的,所以设置完 e.setOpaque(false),还要把它的子FormatttedTextField
|
||||
//设置成透明,其实它的子只有1个,它里为了适用未来的扩展假设它有很多子,
|
||||
Component[] childs = e.getComponents();
|
||||
BEUtils.componentsOpaque(childs, false);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint.
|
||||
*
|
||||
* @param g the g
|
||||
* @param c the c {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
if (spinner != null)
|
||||
ICON_9.getWithEnabled("", spinner.isEnabled()).
|
||||
draw((Graphics2D) g, 0, 0, c.getWidth(), c.getHeight());
|
||||
super.paint(g, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component createPreviousButton() {
|
||||
JButton xpButton = new GlyphButton(spinner, Type.down);
|
||||
Dimension size = UIManager.getDimension("Spinner.arrowButtonSize");
|
||||
xpButton.setPreferredSize(size);
|
||||
xpButton.setRequestFocusEnabled(false);
|
||||
installPreviousButtonListeners(xpButton);
|
||||
return xpButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component createNextButton() {
|
||||
JButton xpButton = new GlyphButton(spinner, Type.up);
|
||||
Dimension size = UIManager.getDimension("Spinner.arrowButtonSize");
|
||||
xpButton.setPreferredSize(size);
|
||||
xpButton.setRequestFocusEnabled(false);
|
||||
installNextButtonListeners(xpButton);
|
||||
return xpButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.sun.java.swing.plaf.windows.XPStyle.GlyphButton
|
||||
*/
|
||||
static class GlyphButton extends JButton {
|
||||
|
||||
private Type type = null;
|
||||
|
||||
/**
|
||||
* The Enum Type.
|
||||
*/
|
||||
public enum Type {
|
||||
down,
|
||||
up
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new glyph button.
|
||||
*
|
||||
* @param parent the parent
|
||||
* @param type the type
|
||||
*/
|
||||
public GlyphButton(Component parent, Type type) {
|
||||
// XPStyle xp = getXP();
|
||||
// skin = xp.getSkin(parent, part);
|
||||
this.type = type;
|
||||
setBorder(null);
|
||||
setContentAreaFilled(false);
|
||||
setMinimumSize(new Dimension(5, 5));
|
||||
setPreferredSize(new Dimension(16, 16));
|
||||
setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFocusTraversable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
ICON_9.get("button_" + type.name(), !isEnabled() || getModel().isPressed() ? "pressed" : "").
|
||||
draw((Graphics2D) g, 0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBorder(Graphics g) {
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.spinner;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
put("Spinner.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("Spinner.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("SpinnerUI", BESpinnerUI.class);
|
||||
|
||||
//Spinner组件的边框
|
||||
putBorder("Spinner.border", 5, 5, 10, 5); // 3, 3, 3, 3
|
||||
//Spinner组件的2个箭头按钮的内衬距
|
||||
putInsets("Spinner.arrowButtonInsets", 1, 0, 2, 2); // 1, 1, 1, 1
|
||||
//Spinner组件的2个箭头按钮的默认大小
|
||||
putDim("Spinner.arrowButtonSize", 17, 9);
|
||||
}
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BESplitPaneDivider.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.split;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneDivider;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* 分栏面板上的分隔线实现类.
|
||||
* <p>
|
||||
* TODO 两个Touch按钮的位置等都是可以定制的,目前没有更好的美化灵感,以后可以再深入优先。
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-07-13
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BESplitPaneDivider extends BasicSplitPaneDivider {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("split_touch");
|
||||
|
||||
private final int oneTouchSize;
|
||||
|
||||
/**
|
||||
* TODO 本常量可以做成UIManager属性以便未来使用者进行配置哦.
|
||||
*/
|
||||
protected final Color TOUCH_BUTTON_COLOR = new Color(58, 135, 173);
|
||||
|
||||
/**
|
||||
* 在水平SplitePane状态下,中间触碰装饰区装饰按钮的宽度.
|
||||
*/
|
||||
protected final static int TOUCH_DECRATED_BUTTON_W = 5;//* TODO 本常量可以做成UIManager属性以便未来使用者进行配置哦
|
||||
|
||||
/**
|
||||
* 在水平SplitePane状态下,中间触碰装饰区装饰按钮的高度.
|
||||
*/
|
||||
protected final static int TOUCH_DECRATED_BUTTON_H = 30;//* TODO 本常量可以做成UIManager属性以便未来使用者进行配置哦
|
||||
|
||||
/**
|
||||
* 分隔条线直线的颜色.
|
||||
*/
|
||||
protected final static Color TOUCH_DECRATED_BUTTON_COLOR = new Color(180, 180, 180);//* TODO 本颜色常量可以做成UIManager属性以便未来使用者进行配置哦
|
||||
|
||||
/**
|
||||
* 分隔条线直线的高亮颜色(用来形成高对比度的立体效果) .
|
||||
*/
|
||||
protected final static Color TOUCH_DECRATED_BUTTON_HILIGHT_COLOR = Color.white;//* TODO 本颜色常量可以做成UIManager属性以便未来使用者进行配置哦
|
||||
|
||||
public BESplitPaneDivider(BasicSplitPaneUI ui) {
|
||||
super(ui);
|
||||
oneTouchSize = UIManager.getInt("SplitPane.oneTouchButtonSize", ui.getSplitPane().getLocale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Color bgColor = (splitPane.hasFocus())
|
||||
? UIManager.getColor("SplitPane.shadow") : getBackground();
|
||||
Dimension size = getSize();
|
||||
Graphics2D g2 = ((Graphics2D) g);
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, true);
|
||||
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
// RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
if (bgColor != null) {
|
||||
int orient = this.splitPane.getOrientation();
|
||||
if (orient == JSplitPane.HORIZONTAL_SPLIT) {
|
||||
int halfWidth = size.width / 2;
|
||||
int halfHeight = size.height / 2;
|
||||
|
||||
//------------------------先水平居中画隔条竖线
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);
|
||||
|
||||
g.setColor(TOUCH_DECRATED_BUTTON_COLOR);//bgColor);
|
||||
// g.fillRect(0, 0, size.width, size.height);
|
||||
g.drawLine(halfWidth + 0, 0, halfWidth + 0, size.height);
|
||||
//在竖线右边再画一个高对比度的竖线从而形成立体效果
|
||||
g.setColor(TOUCH_DECRATED_BUTTON_HILIGHT_COLOR);
|
||||
g.drawLine(halfWidth + 1, 0, halfWidth + 1, size.height);
|
||||
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
|
||||
//------------------------再填充触碰装饰区
|
||||
int decratedButton_w = TOUCH_DECRATED_BUTTON_W;
|
||||
int decratedButton_h = TOUCH_DECRATED_BUTTON_H;//18;
|
||||
int diverTouchStartX = halfWidth - decratedButton_w / 2;
|
||||
ICON_9.get("bg1")
|
||||
.draw((Graphics2D) g, diverTouchStartX, halfHeight - decratedButton_h / 2,
|
||||
decratedButton_w, decratedButton_h);
|
||||
} else {
|
||||
int halfHeight = size.height / 2;
|
||||
int halfWidth = size.width / 2;
|
||||
|
||||
//------------------------先垂直居中画分隔条横线
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);
|
||||
|
||||
g.setColor(TOUCH_DECRATED_BUTTON_COLOR);//bgColor);
|
||||
// g.fillRect(0, 0, size.width, size.height);
|
||||
g.drawLine(0, halfHeight + 0, size.width, halfHeight + 0);
|
||||
//在竖线下边再画一个高对比度的横线从而形成立体效果
|
||||
g.setColor(TOUCH_DECRATED_BUTTON_HILIGHT_COLOR);
|
||||
g.drawLine(0, halfHeight + 1, size.width, halfHeight + 1);
|
||||
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
|
||||
//------------------------再填充触碰装饰区
|
||||
int decratedButton_w = TOUCH_DECRATED_BUTTON_W;
|
||||
int decratedButton_h = TOUCH_DECRATED_BUTTON_H;//18;
|
||||
int diverTouchStartY = halfHeight - decratedButton_w / 2;
|
||||
ICON_9.get("bg1")
|
||||
.draw((Graphics2D) g, halfWidth - decratedButton_h, diverTouchStartY,
|
||||
decratedButton_h, decratedButton_w);
|
||||
}
|
||||
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
// RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, false);
|
||||
}
|
||||
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and return an instance of JButton that can be used to collapse
|
||||
* the left component in the split pane.
|
||||
*
|
||||
* 因父类方法继承重用设计不佳,此处只能全部拷过来代码,再行修改。
|
||||
* 至2012-07-13:本方法只作了关于箭头按钮的填充颜色的改变。
|
||||
*
|
||||
* @return the j button
|
||||
* @see javax.swing.plaf.basic.BasicSplitPaneDivider#createLeftOneTouchButton()
|
||||
*/
|
||||
@Override
|
||||
protected JButton createLeftOneTouchButton() {
|
||||
JButton b = new JButton() {
|
||||
@Override
|
||||
public void setBorder(Border b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (splitPane != null) {
|
||||
int[] xs = new int[3];
|
||||
int[] ys = new int[3];
|
||||
int blockSize;
|
||||
|
||||
// Fill the background first ...
|
||||
g.setColor(this.getBackground());
|
||||
g.fillRect(0, 0, this.getWidth(), this.getHeight());
|
||||
|
||||
// ... then draw the arrow.
|
||||
g.setColor(TOUCH_BUTTON_COLOR);//Color.black);
|
||||
|
||||
//* 开启反走样
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, true);
|
||||
|
||||
if (orientation == JSplitPane.VERTICAL_SPLIT) {
|
||||
blockSize = Math.min(getHeight(), oneTouchSize);
|
||||
xs[0] = blockSize;
|
||||
xs[1] = 0;
|
||||
xs[2] = blockSize << 1;
|
||||
ys[0] = 0;
|
||||
ys[1] = ys[2] = blockSize;
|
||||
g.drawPolygon(xs, ys, 3); // Little trick to make the
|
||||
// arrows of equal size
|
||||
} else {
|
||||
blockSize = Math.min(getWidth(), oneTouchSize);
|
||||
xs[0] = xs[2] = blockSize;
|
||||
xs[1] = 0;
|
||||
ys[0] = 0;
|
||||
ys[1] = blockSize;
|
||||
ys[2] = blockSize << 1;
|
||||
}
|
||||
g.fillPolygon(xs, ys, 3);
|
||||
|
||||
//* 关闭反走样
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't want the button to participate in focus traversable.
|
||||
@Override
|
||||
public boolean isFocusTraversable() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
|
||||
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
b.setFocusPainted(false);
|
||||
b.setBorderPainted(false);
|
||||
b.setRequestFocusEnabled(false);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and return an instance of JButton that can be used to collapse
|
||||
* the right component in the split pane.
|
||||
*
|
||||
* 因父类方法继承重用设计不佳,此处只能全部拷过来代码,再行修改。
|
||||
* 至2012-07-13:本方法只作了关于箭头按钮的填充颜色的改变。
|
||||
*
|
||||
* @return the j button
|
||||
* @see javax.swing.plaf.basic.BasicSplitPaneDivider#createRightOneTouchButton()
|
||||
*/
|
||||
@Override
|
||||
protected JButton createRightOneTouchButton() {
|
||||
JButton b = new JButton() {
|
||||
@Override
|
||||
public void setBorder(Border border) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (splitPane != null) {
|
||||
int[] xs = new int[3];
|
||||
int[] ys = new int[3];
|
||||
int blockSize;
|
||||
|
||||
// Fill the background first ...
|
||||
g.setColor(this.getBackground());
|
||||
g.fillRect(0, 0, this.getWidth(),
|
||||
this.getHeight());
|
||||
|
||||
//* 开启反走样
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, true);
|
||||
|
||||
// ... then draw the arrow.
|
||||
if (orientation == JSplitPane.VERTICAL_SPLIT) {
|
||||
blockSize = Math.min(getHeight(), oneTouchSize);
|
||||
xs[0] = blockSize;
|
||||
xs[1] = blockSize << 1;
|
||||
xs[2] = 0;
|
||||
ys[0] = blockSize;
|
||||
ys[1] = ys[2] = 0;
|
||||
} else {
|
||||
blockSize = Math.min(getWidth(), oneTouchSize);
|
||||
xs[0] = xs[2] = 0;
|
||||
xs[1] = blockSize;
|
||||
ys[0] = 0;
|
||||
ys[1] = blockSize;
|
||||
ys[2] = blockSize << 1;
|
||||
}
|
||||
|
||||
g.setColor(TOUCH_BUTTON_COLOR);//Color.black);
|
||||
|
||||
g.fillPolygon(xs, ys, 3);
|
||||
|
||||
//* 关闭反走样
|
||||
BEUtils.setAntiAliasing((Graphics2D) g, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't want the button to participate in focus traversable.
|
||||
@Override
|
||||
public boolean isFocusTraversable() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
|
||||
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
b.setFocusPainted(false);
|
||||
b.setBorderPainted(false);
|
||||
b.setRequestFocusEnabled(false);
|
||||
return b;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BESplitPaneUI.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.split;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneDivider;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneUI;
|
||||
|
||||
/**
|
||||
* 分栏面板的UI实现.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-07-10
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BESplitPaneUI extends BasicSplitPaneUI {
|
||||
|
||||
public BESplitPaneUI() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static ComponentUI createUI(JComponent x) {
|
||||
return new BESplitPaneUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicSplitPaneDivider createDefaultDivider() {
|
||||
return new BESplitPaneDivider(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* SplitPaneDividerBorder.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.split;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneDivider;
|
||||
import javax.swing.plaf.basic.BasicSplitPaneUI;
|
||||
|
||||
/**
|
||||
* 分隔条的border实现类.
|
||||
* <p>
|
||||
* Draws the border around the divider in a splitpane. To get the appropriate
|
||||
* effect, this needs to be used with a SplitPaneBorder.
|
||||
*
|
||||
* 主要修改了UI填充实现部分
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see javax.swing.plaf.basic.BasicBorders
|
||||
*/
|
||||
public class SplitPaneDividerBorder implements Border, UIResource {
|
||||
// javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder
|
||||
// private Color highlight;
|
||||
// private Color shadow;
|
||||
|
||||
// public SplitPaneDividerBorder(Color highlight, Color shadow)
|
||||
// {
|
||||
// this.highlight = highlight;
|
||||
// this.shadow = shadow;
|
||||
// }
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width,
|
||||
int height) {
|
||||
//在目前的视觉效果下不需要这个border的绘制哦
|
||||
// Graphics2D g2d = (Graphics2D) g;
|
||||
// Component child;
|
||||
// Rectangle cBounds;
|
||||
// JSplitPane splitPane = ((BasicSplitPaneDivider) c).getBasicSplitPaneUI().getSplitPane();
|
||||
// Dimension size = c.getSize();
|
||||
//
|
||||
// child = splitPane.getLeftComponent();
|
||||
// // This is needed for the space between the divider and end of
|
||||
// // splitpane.
|
||||
// g.setColor(c.getBackground());
|
||||
// g.drawRect(x, y, width - 1, height - 1);
|
||||
//
|
||||
// if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
|
||||
// {
|
||||
//// if (child != null)
|
||||
//// {
|
||||
//// g.setColor(shadow);//highlight);
|
||||
//// g.drawLine(0, 0, 0, size.height);
|
||||
//// }
|
||||
//// child = splitPane.getRightComponent();
|
||||
//// if (child != null)
|
||||
//// {
|
||||
//// g.setColor(shadow);
|
||||
//// g.drawLine(size.width - 1, 0, size.width - 1, size.height);
|
||||
//// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//// if (child != null)
|
||||
//// {
|
||||
//// g.setColor(shadow);//highlight);
|
||||
//// g.drawLine(0, 0, size.width, 0);
|
||||
//// }
|
||||
//// child = splitPane.getRightComponent();
|
||||
//// if (child != null)
|
||||
//// {
|
||||
//// g.setColor(shadow);
|
||||
//// g.drawLine(0, size.height - 1, size.width,size.height - 1);
|
||||
////
|
||||
//// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
Insets insets = new Insets(0, 0, 0, 0);
|
||||
if (c instanceof BasicSplitPaneDivider) {
|
||||
BasicSplitPaneUI bspui = ((BasicSplitPaneDivider) c)
|
||||
.getBasicSplitPaneUI();
|
||||
|
||||
if (bspui != null) {
|
||||
JSplitPane splitPane = bspui.getSplitPane();
|
||||
|
||||
if (splitPane != null) {
|
||||
if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
|
||||
insets.top = insets.bottom = 0;
|
||||
insets.left = insets.right = 1;
|
||||
return insets;
|
||||
}
|
||||
// VERTICAL_SPLIT
|
||||
insets.top = insets.bottom = 1;
|
||||
insets.left = insets.right = 0;
|
||||
return insets;
|
||||
}
|
||||
}
|
||||
}
|
||||
insets.top = insets.bottom = insets.left = insets.right = 1;
|
||||
return insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.split;
|
||||
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
putColor("SplitPane.shadow", 200, 200, 200); // 本属性在BE LNF中暂时没用到
|
||||
//JSplitePane的默认背景色
|
||||
putColor("SplitPane.background", 250, 250, 250); // 238, 241, 243
|
||||
//JSplitePane的边框实现
|
||||
put("SplitPane.border", new org.jackhuang.hmcl.laf.scroll.ScrollPaneBorder());// 0, 0, 0, 0
|
||||
put("SplitPaneUI", BESplitPaneUI.class);
|
||||
|
||||
//分隔条拖动时的颜色(说明:此值可以设置alpha通道以便达到半透明效果哦)
|
||||
putColor("SplitPaneDivider.draggingColor", 0, 0, 0, 50);
|
||||
//触碰按钮的默认大小
|
||||
// see javax.swing.plaf.basic.BasicSplitPaneDivider.ONE_TOUCH_SIZE = 6
|
||||
put("SplitPane.oneTouchButtonSize", 4);
|
||||
//分隔条的默认大小
|
||||
put("SplitPane.dividerSize", 7); //drfault is 5
|
||||
//分隔条的边框实现
|
||||
put("SplitPaneDivider.border", new SplitPaneDividerBorder());
|
||||
}
|
||||
}
|
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETabbedPaneUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.tab;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
|
||||
/**
|
||||
* JTabbedPane的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-01-12
|
||||
* @version 1.1
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsTabbedPaneUI
|
||||
*/
|
||||
public class BETabbedPaneUI extends BasicTabbedPaneUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BETabbedPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* 本方法的重写copy自 com.sun.java.swing.plaf.windows.WindowsTabbedPaneUI,基本未修改代码
|
||||
* 重写父类方法实现rover状态下的tab的ui重绘(父类方法只是实现了rolloverTab 的设置,不步及ui重绘制,因Basic
|
||||
* LNF中没有实现rover状态的ui样式)
|
||||
*
|
||||
* @see javax.swing.plaf.basic.BasicTabbedPaneUI#setRolloverTab(int)
|
||||
*/
|
||||
@Override
|
||||
protected void setRolloverTab(int index) {
|
||||
int oldRolloverTab = getRolloverTab();
|
||||
super.setRolloverTab(index);
|
||||
Rectangle r1 = null;
|
||||
Rectangle r2 = null;
|
||||
if ((oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount()))
|
||||
r1 = getTabBounds(tabPane, oldRolloverTab);
|
||||
if (index >= 0)
|
||||
r2 = getTabBounds(tabPane, index);
|
||||
if (r1 != null)
|
||||
if (r2 != null)
|
||||
tabPane.repaint(r1.union(r2));
|
||||
else
|
||||
tabPane.repaint(r1);
|
||||
else if (r2 != null)
|
||||
tabPane.repaint(r2);
|
||||
}
|
||||
|
||||
/**
|
||||
* this function draws the border around each tab note that this function
|
||||
* does now draw the background of the tab. that is done elsewhere.
|
||||
*
|
||||
* @param g the g
|
||||
* @param tabPlacement the tab placement
|
||||
* @param tabIndex the tab index
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param w the w
|
||||
* @param h the h
|
||||
* @param isSelected the is selected
|
||||
* @see javax.swing.plaf.basic.BasicTabbedPaneUI#paintTabBorder(java.awt.Graphics, int, int, int, int, int, int, boolean)
|
||||
*/
|
||||
@Override
|
||||
protected void paintTabBorder(Graphics g, int tabPlacement,
|
||||
int tabIndex, int x, int y, int w, int h, boolean isSelected) {
|
||||
// g.setColor(lightHighlight);
|
||||
// Graphics2D g2d = (Graphics2D)g;
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
g2d.translate(x, y);
|
||||
|
||||
//* 由Jack Jiang添加:true表示该tab当前正处于鼠标rover其上的状态
|
||||
//* this.getRolloverTab()的返回值由父类方法 setRolloverTab()设定并实现ui重绘的
|
||||
boolean isRover = (this.getRolloverTab() == tabIndex);
|
||||
//* 由Jack Jiang添加:true表示该tab处于可用状态,否则表示处于禁用状态
|
||||
boolean isEnableAt = this.tabPane.isEnabledAt(tabIndex);
|
||||
|
||||
switch (tabPlacement) {
|
||||
case LEFT:
|
||||
g2d.scale(-1.0, 1.0);
|
||||
g2d.rotate(Math.toRadians(90.0));
|
||||
paintTabBorderImpl(g2d, isEnableAt, isSelected, isRover, 0, 0, h, w);
|
||||
break;
|
||||
case RIGHT:
|
||||
g2d.translate(w, 0);
|
||||
g2d.rotate(Math.toRadians(90.0));
|
||||
paintTabBorderImpl(g2d, isEnableAt, isSelected, isRover, 0, 0, h, w);
|
||||
break;
|
||||
case BOTTOM:
|
||||
g2d.translate(0, h);
|
||||
g2d.scale(-1.0, 1.0);
|
||||
g2d.rotate(Math.toRadians(180.0));
|
||||
paintTabBorderImpl(g2d, isEnableAt, isSelected, isRover, 0, 0, w, h);
|
||||
break;
|
||||
case TOP:
|
||||
default:
|
||||
paintTabBorderImpl(g2d, isEnableAt, isSelected, isRover, 0, 0, w, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//* paintTabBorder的绘制实现方法,2012-01-12日 BY Jack Jiang
|
||||
|
||||
/**
|
||||
* Paint tab border impl.
|
||||
*
|
||||
* @param g2d the g2d
|
||||
* @param isEnableAt the is enable at
|
||||
* @param isSelected the is selected
|
||||
* @param isRover the is rover
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param w the w
|
||||
* @param h the h
|
||||
*/
|
||||
private void paintTabBorderImpl(Graphics2D g2d, boolean isEnableAt, boolean isSelected,
|
||||
boolean isRover, int x, int y, int w, int h) {
|
||||
//** modified by jb2011 改为NinePatch图片实现,Y + 1 的目的是使得选中时的底线能往下画一个像素(这样好看点)
|
||||
if (isSelected) {
|
||||
g2d.setColor(UIManager.getColor("TabbedPane.selectedForeground"));
|
||||
g2d.fillRect(x, y + h - 1, w, 2);
|
||||
}
|
||||
//ICON_9.get("", isSelected ? "selected" : (isEnableAt && isRover ? "normal_rollover" : "normal"))
|
||||
// .draw(g2d, x, y + 1, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写本方法的目的仅是把原来的默认实线变成虚线而已哦
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintContentBorder(java.awt.Graphics,
|
||||
* int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
|
||||
/*//*** add by jb2011 2012-08-23 START
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);
|
||||
//*** add by jb2011 2012-08-23 END
|
||||
*/
|
||||
//调用父类默认实现
|
||||
super.paintContentBorder(g, tabPlacement, selectedIndex);
|
||||
/*
|
||||
//*** add by jb2011 2012-08-23 START
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
//*** add by jb2011 2012-08-23 END*/
|
||||
}
|
||||
|
||||
//
|
||||
/**
|
||||
* JTabbedPaneUI 内容面板的上边框绘制方法(默认就是内容面板上方的那条灰色).
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintContentBorderTopEdge(java.awt.Graphics,
|
||||
* int, int, int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
|
||||
int selectedIndex,
|
||||
int x, int y, int w, int h) {
|
||||
//此模式下不绘制其它3条边框,视觉上好看一些
|
||||
if (tabPlacement == TOP)
|
||||
//调用父类默认实现
|
||||
super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* JTabbedPaneUI 内容面板的左边框绘制方法.
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintContentBorderLeftEdge(java.awt.Graphics,
|
||||
* int, int, int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
|
||||
int selectedIndex,
|
||||
int x, int y, int w, int h) {
|
||||
//此模式下不绘制其它3条边框,视觉上好看一些
|
||||
if (tabPlacement == LEFT)
|
||||
//调用父类默认实现
|
||||
super.paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* JTabbedPaneUI 内容面板的底边框绘制方法.
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintContentBorderBottomEdge(java.awt.Graphics,
|
||||
* int, int, int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
|
||||
int selectedIndex,
|
||||
int x, int y, int w, int h) {
|
||||
//此模式下不绘制其它3条边框,视觉上好看一些
|
||||
if (tabPlacement == BOTTOM)
|
||||
//调用父类默认实现
|
||||
super.paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* JTabbedPaneUI 内容面板的右边框绘制方法.
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintContentBorderRightEdge(java.awt.Graphics,
|
||||
* int, int, int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
|
||||
int selectedIndex,
|
||||
int x, int y, int w, int h) {
|
||||
//此模式下不绘制其它3条边框,视觉上好看一些
|
||||
if (tabPlacement == RIGHT)
|
||||
//调用父类默认实现
|
||||
super.paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得焦点时的虚线框绘制方法
|
||||
*
|
||||
* @see
|
||||
* javax.swing.plaf.basic.BasicTabbedPaneUI#paintFocusIndicator(java.awt.Graphics,
|
||||
* int, java.awt.Rectangle[], int, java.awt.Rectangle, java.awt.Rectangle,
|
||||
* boolean)
|
||||
*/
|
||||
@Override
|
||||
protected void paintFocusIndicator(Graphics g, int tabPlacement,
|
||||
Rectangle[] rects, int tabIndex,
|
||||
Rectangle iconRect, Rectangle textRect,
|
||||
boolean isSelected) {
|
||||
Rectangle tabRect = rects[tabIndex];
|
||||
if (tabPane.hasFocus() && isSelected) {
|
||||
int x, y, w, h;
|
||||
g.setColor(focus);
|
||||
switch (tabPlacement) {
|
||||
case LEFT:
|
||||
x = tabRect.x + 4;//父类中默认是+3
|
||||
y = tabRect.y + 6;//父类中默认是+3
|
||||
w = tabRect.width - 7;//父类中默认是 - 5
|
||||
h = tabRect.height - 12;//父类中默认是-6
|
||||
break;
|
||||
case RIGHT:
|
||||
x = tabRect.x + 4;//父类中默认是+ 2
|
||||
y = tabRect.y + 6;//父类中默认是+ 3
|
||||
w = tabRect.width - 9;//父类中默认是- 5
|
||||
h = tabRect.height - 12;//父类中默认是- 6
|
||||
break;
|
||||
case BOTTOM:
|
||||
x = tabRect.x + 6;//父类中默认是+ 3
|
||||
y = tabRect.y + 4;//父类中默认是+ 2
|
||||
w = tabRect.width - 12;//父类中默认是- 6
|
||||
h = tabRect.height - 9;//父类中默认是- 5
|
||||
break;
|
||||
case TOP:
|
||||
default:
|
||||
//** modified by jb2011:根据整体效果进行偏移修正
|
||||
x = tabRect.x + 6;//父类中默认是+3
|
||||
//** modified by jb2011:根据整体效果进行偏移修正
|
||||
y = tabRect.y + 4;//父类中默认是+3
|
||||
//** modified by jb2011:根据整体效果进行偏移修正
|
||||
w = tabRect.width - 12;//父类中默认是-6
|
||||
//** modified by jb2011:-8的目的是使得焦点虚线框与选中底边保持一个像素的距离,否则挨在一起在视觉上效果会较差
|
||||
h = tabRect.height - 8;//父类中默认是 - 5
|
||||
}
|
||||
|
||||
//** modified by jb2011:绘制虚线方法改成可以设置虚线步进的方法,步进设为2则更好看一点
|
||||
// BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
|
||||
BEUtils.drawDashedRect(g, x, y, w, h);
|
||||
// 绘制虚线框的半透明白色立体阴影(因主背景色较淡,效果不明显,但显然比没有要好)
|
||||
g.setColor(new Color(255, 255, 255, 255));// TODO 此值可提炼成UIManager属性哦
|
||||
// 立体阴影就是向右下偏移一个像素实现的
|
||||
BEUtils.drawDashedRect(g, x + 1, y + 1, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写并修改本方法的目的是修正tab上的文本显示Y坐标方向上的偏移,以便与背景协调
|
||||
* @see javax.swing.plaf.basic.BasicTabbedPaneUI#getTabLabelShiftY(int, int, boolean)
|
||||
*/
|
||||
@Override
|
||||
protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) {
|
||||
return 0;
|
||||
/*
|
||||
switch (tabPlacement) {
|
||||
case BOTTOM:
|
||||
return isSelected ? 1 : -1;
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
return rects[tabIndex].height % 2;
|
||||
case TOP:
|
||||
default:
|
||||
//** 由jb2011 2012-08-24修改:目的是使得选中时和未选中时的文本(包括图标
|
||||
//** 默认实现中之所以要产生它个效果是为了营造立体效果,而BE LNF中并不需要
|
||||
//** )不要往上或往下偏移的太多(太多则相当难看)
|
||||
// nudge = isSelected? -1 : 1;//本行是原父类中的默认实现哦
|
||||
return -2;//由jb2011修改,目的是让文本相对现在的背景往上偏移一点,好看一些
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) {
|
||||
Rectangle tabRect = rects[tabIndex];
|
||||
String propKey = "labelShift";
|
||||
int nudge = UIManager.getInt("TabbedPane." + propKey);
|
||||
|
||||
switch (tabPlacement) {
|
||||
case LEFT:
|
||||
return nudge;
|
||||
case RIGHT:
|
||||
return -nudge;
|
||||
case BOTTOM:
|
||||
case TOP:
|
||||
default:
|
||||
return tabRect.width % 2;
|
||||
}
|
||||
}
|
||||
}
|
51
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/__UI__.java
Normal file
51
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/__UI__.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.tab;
|
||||
|
||||
import java.awt.Font;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
public static void uiImpl() {
|
||||
FontUIResource f = (FontUIResource) UIManager.get("TabbedPane.font");
|
||||
UIManager.put("TabbedPane.font", new FontUIResource(new Font(f.getName(), f.getStyle(), 14)));
|
||||
put("TabbedPane.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("TabbedPane.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("TabbedPane.opaque", false);
|
||||
// put("TabbedPane.tabRunOverlay", 2);//本属性无效果
|
||||
//false表示tab在边框虑线之上而不是重叠效果
|
||||
put("TabbedPane.tabsOverlapBorder", true);
|
||||
put("TabbedPaneUI", BETabbedPaneUI.class);
|
||||
//此属性决定了整个JTabbedPane区域的内衬
|
||||
putInsets("TabbedPane.tabAreaInsets", 3, 20, 2, 20);// 3, 2, 2, 2
|
||||
//此属性决定了tab与内容面板间的空白
|
||||
putInsets("TabbedPane.contentBorderInsets", 2, 0, 3, 0);// 2, 2, 3, 3
|
||||
//此参数将决定选中时的tab与左右相邻tab的重合度,正值表示重合、负值表示间隔(空白)
|
||||
//* 注意与NP图的边缘留白配合使用能达到更灵活的效果
|
||||
putInsets("TabbedPane.selectedTabPadInsets", 0, 1, 0, 2);// 2, 2, 2, 1
|
||||
//此属性决定了JTabbedPane的tab标签的内衬
|
||||
putInsets("TabbedPane.tabInsets", 7, 7, 7, 7);
|
||||
//获得焦点时的虚线框颜色
|
||||
putColor("TabbedPane.focus", 130, 130, 130);
|
||||
//在BE LNF中,此颜色将决定TabPlacement=TOP和LEFT二种类型TabbedPane的内容面板那条虚线的颜色
|
||||
putColor("TabbedPane.highlight", 228, 228, 231);//new Color(200,200,200)));
|
||||
//在BE LNF中,此颜色将决定TabPlacement=RIGHT和BOTTOM二种类型TabbedPane的内容面板那条虚线的颜色
|
||||
put("TabbedPane.shadow", BeautyEyeLNFHelper.commonFocusedBorderColor);//192,192,192);
|
||||
//在BE LNF中,因TabPlacement=RIGHT和BOTTOM二种类型时,父类方法会默认再多画一条深色立体线而使得在BE LNF中
|
||||
//不好看,此颜色设置的目的就是让此立体阴影线与背景色一致从而看不出它的效果,进而不影响内容面板那条虚线在BE LNF中的视觉效果
|
||||
put("TabbedPane.darkShadow", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
}
|
||||
}
|
@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETableHeaderUI.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.table;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.RowSorter;
|
||||
import javax.swing.SortOrder;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
|
||||
/**
|
||||
* 表格头UI实现类。
|
||||
* <p>
|
||||
* 本类代码只能用于JDK1.6及以上版本,因JDK1.5及以下版本没法兼容本类中的很大一部分关键代码。
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2011-03-28
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsTableHeaderUI
|
||||
*/
|
||||
public class BETableHeaderUI extends BasicTableHeaderUI {
|
||||
|
||||
protected static final Icon9Factory ICON_9 = new Icon9Factory("table");
|
||||
|
||||
private TableCellRenderer originalHeaderRenderer;
|
||||
|
||||
public static ComponentUI createUI(JComponent h) {
|
||||
return new BETableHeaderUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
originalHeaderRenderer = header.getDefaultRenderer();
|
||||
if (originalHeaderRenderer instanceof UIResource)
|
||||
header.setDefaultRenderer(new XPDefaultRenderer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallUI(JComponent c) {
|
||||
if (header.getDefaultRenderer() instanceof XPDefaultRenderer)
|
||||
header.setDefaultRenderer(originalHeaderRenderer);
|
||||
super.uninstallUI(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
|
||||
header.repaint(header.getHeaderRect(oldColumn));
|
||||
header.repaint(header.getHeaderRect(newColumn));
|
||||
}
|
||||
|
||||
//绘制头Ui内容,本方法提取出来是为了在ELineNumTable里也可以用到(它是进行了自定义Ui头实现)
|
||||
/**
|
||||
* Paint head cell.
|
||||
*
|
||||
* @param g the g
|
||||
* @param headCellSize the head cell size
|
||||
*/
|
||||
public static void paintHeadCell(Graphics g, Dimension headCellSize) {
|
||||
int w = headCellSize.width, h = headCellSize.height - 1;
|
||||
|
||||
// Graphics2D g2 = (Graphics2D)g;
|
||||
// //渐变背景
|
||||
// Paint oldp= g2.getPaint();
|
||||
// GradientPaint gp = new GradientPaint(0, 0
|
||||
// , new Color(250,250,250)
|
||||
// , 0, h,new Color(241,241,241));
|
||||
// g2.setPaint(gp);
|
||||
// g.fillRect(0, 0, w, h);
|
||||
// //矩形区下1/2处非渐变填充(为了产生立体效果)
|
||||
// g2.setPaint(oldp);
|
||||
//
|
||||
// //上下线条,突出立体感
|
||||
// g.setColor(new Color(215,215,215));
|
||||
// g.drawLine(0, 0, w, 0);
|
||||
// g.setColor(new Color(249,250,249));
|
||||
// g.drawLine(0, h-1, w, h-1);
|
||||
// g.setColor(new Color(209,209,209));
|
||||
// g.drawLine(0, h, w, h);
|
||||
ICON_9.get("header_cell")
|
||||
.draw((Graphics2D) g, 0, 0, w, h);//表头背景
|
||||
ICON_9.get("header_cell_separator")
|
||||
.draw((Graphics2D) g, w - 2, 0, 4, h - 1);//表头右边的分隔线,h-1是为了让分隔线往上移一个像素,好看一点
|
||||
}
|
||||
|
||||
public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
|
||||
implements UIResource {
|
||||
|
||||
private boolean horizontalTextPositionSet;
|
||||
private Icon sortArrow;
|
||||
private final EmptyIcon emptyIcon = new EmptyIcon();
|
||||
|
||||
public DefaultTableCellHeaderRenderer() {
|
||||
setHorizontalAlignment(JLabel.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHorizontalTextPosition(int textPosition) {
|
||||
horizontalTextPositionSet = true;
|
||||
super.setHorizontalTextPosition(textPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
Icon sortIcon = null;
|
||||
|
||||
boolean isPaintingForPrint = false;
|
||||
|
||||
if (table != null) {
|
||||
JTableHeader header = table.getTableHeader();
|
||||
if (header != null) {
|
||||
Color fgColor = null;
|
||||
Color bgColor = null;
|
||||
if (hasFocus) {
|
||||
fgColor = UIManager.getColor("TableHeader.focusCellForeground", this.getLocale());
|
||||
bgColor = UIManager.getColor("TableHeader.focusCellBackground", this.getLocale());
|
||||
}
|
||||
if (fgColor == null)
|
||||
fgColor = header.getForeground();
|
||||
if (bgColor == null)
|
||||
bgColor = header.getBackground();
|
||||
setForeground(fgColor);
|
||||
setBackground(bgColor);
|
||||
|
||||
setFont(header.getFont());
|
||||
|
||||
isPaintingForPrint = header.isPaintingForPrint();
|
||||
}
|
||||
|
||||
if (!isPaintingForPrint && table.getRowSorter() != null) {
|
||||
if (!horizontalTextPositionSet)
|
||||
// There is a row sorter, and the developer hasn't
|
||||
// set a text position, change to leading.
|
||||
setHorizontalTextPosition(JLabel.LEADING);
|
||||
SortOrder sortOrder = getColumnSortOrder(table, column);
|
||||
if (sortOrder != null)
|
||||
switch (sortOrder) {
|
||||
case ASCENDING:
|
||||
sortIcon = UIManager.getIcon("Table.ascendingSortIcon", this.getLocale());
|
||||
break;
|
||||
case DESCENDING:
|
||||
sortIcon = UIManager.getIcon("Table.descendingSortIcon", this.getLocale());
|
||||
break;
|
||||
case UNSORTED:
|
||||
sortIcon = UIManager.getIcon("Table.naturalSortIcon", this.getLocale());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setText(value == null ? "" : value.toString());
|
||||
setIcon(sortIcon);
|
||||
sortArrow = sortIcon;
|
||||
|
||||
Border border = null;
|
||||
if (hasFocus)
|
||||
border = UIManager.getBorder("TableHeader.focusCellBorder", this.getLocale());
|
||||
if (border == null)
|
||||
border = UIManager.getBorder("TableHeader.cellBorder", this.getLocale());
|
||||
setBorder(border);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public SortOrder getColumnSortOrder(JTable table, int column) {
|
||||
SortOrder rv = null;
|
||||
if (table == null || table.getRowSorter() == null)
|
||||
return rv;
|
||||
java.util.List<? extends RowSorter.SortKey> sortKeys
|
||||
= table.getRowSorter().getSortKeys();
|
||||
if (sortKeys.size() > 0 && sortKeys.get(0).getColumn()
|
||||
== table.convertColumnIndexToModel(column))
|
||||
rv = sortKeys.get(0).getSortOrder();
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
boolean b = UIManager.getBoolean("TableHeader.rightAlignSortArrow", this.getLocale());
|
||||
if (b && sortArrow != null) {
|
||||
//emptyIcon is used so that if the text in the header is right
|
||||
//aligned, or if the column is too narrow, then the text will
|
||||
//be sized appropriately to make room for the icon that is about
|
||||
//to be painted manually here.
|
||||
emptyIcon.width = sortArrow.getIconWidth();
|
||||
emptyIcon.height = sortArrow.getIconHeight();
|
||||
setIcon(emptyIcon);
|
||||
super.paintComponent(g);
|
||||
Point position = computeIconPosition(g);
|
||||
sortArrow.paintIcon(this, g, position.x, position.y);
|
||||
} else
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
private Point computeIconPosition(Graphics g) {
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
Rectangle viewR = new Rectangle();
|
||||
Rectangle textR = new Rectangle();
|
||||
Rectangle iconR = new Rectangle();
|
||||
Insets i = getInsets();
|
||||
viewR.x = i.left;
|
||||
viewR.y = i.top;
|
||||
viewR.width = getWidth() - (i.left + i.right);
|
||||
viewR.height = getHeight() - (i.top + i.bottom);
|
||||
SwingUtilities.layoutCompoundLabel(
|
||||
this,
|
||||
fontMetrics,
|
||||
getText(),
|
||||
sortArrow,
|
||||
getVerticalAlignment(),
|
||||
getHorizontalAlignment(),
|
||||
getVerticalTextPosition(),
|
||||
getHorizontalTextPosition(),
|
||||
viewR,
|
||||
iconR,
|
||||
textR,
|
||||
getIconTextGap());
|
||||
int x = getWidth() - i.right - sortArrow.getIconWidth();
|
||||
int y = iconR.y;
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
private class EmptyIcon implements Icon, Serializable {
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class XPDefaultRenderer extends DefaultTableCellHeaderRenderer {
|
||||
|
||||
XPDefaultRenderer() {
|
||||
setHorizontalAlignment(LEADING);
|
||||
setVerticalAlignment(CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
|
||||
//** 本方法里可以有默认设置render字体和颜色的设置,所以即使在上面构造方法里设置自已的字体等都不起效
|
||||
//,在此方法调用之后调置是没有问题的
|
||||
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
// this.isSelected = isSelected;
|
||||
// this.hasFocus = hasFocus;
|
||||
// this.column = column;
|
||||
// this.hasRollover = (column == getRolloverColumn());
|
||||
// if (skin == null)
|
||||
// {
|
||||
// skin = BEXPStyle.getXP().getSkin(header, Part.HP_HEADERITEM);
|
||||
// }
|
||||
Insets margins = UIManager.getInsets("TableHeader.cellMargin");//skin.getContentMargin();
|
||||
Border border;
|
||||
int contentTop = 0;
|
||||
int contentLeft = 0;
|
||||
int contentBottom = 0;
|
||||
int contentRight = 0;
|
||||
if (margins != null) {
|
||||
contentTop = margins.top;
|
||||
contentLeft = margins.left;
|
||||
contentBottom = margins.bottom;
|
||||
contentRight = margins.right;
|
||||
}
|
||||
/* idk:
|
||||
* Both on Vista and XP there is some offset to the
|
||||
* HP_HEADERITEM content. It does not seem to come from
|
||||
* Prop.CONTENTMARGINS. Do not know where it is defined.
|
||||
* using some hardcoded values.
|
||||
*/
|
||||
contentLeft += 5;
|
||||
contentBottom += 4;
|
||||
contentRight += 5;
|
||||
|
||||
/* On Vista sortIcon is painted above the header's text.
|
||||
* We use border to paint it.
|
||||
*/
|
||||
Icon sortIcon;
|
||||
//原UI代码
|
||||
// if (ZCWindowsLookAndFeel.isOnVista()&&
|
||||
// ((sortIcon = getIcon()) instanceof javax.swing.plaf.UIResource
|
||||
// || sortIcon == null))
|
||||
//现代码:上面原Java源代码里有WindowsLookAndFeel.isOnVista()==true时才会进入下面的代码
|
||||
//逻辑是不对的,也就是只要不是vista,就不可能绘制排序图标,这估计是Jdk自带的Java源代码很可能不是最新的!
|
||||
if ( //去掉vista判断
|
||||
// ZCWindowsLookAndFeel.isOnVista()
|
||||
// &&
|
||||
((sortIcon = getIcon()) instanceof javax.swing.plaf.UIResource || sortIcon == null)) {
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高,现注释掉!
|
||||
// contentTop += 1;
|
||||
|
||||
setIcon(null);
|
||||
sortIcon = null;
|
||||
|
||||
SortOrder sortOrder = getColumnSortOrder(table, column);
|
||||
if (sortOrder != null)
|
||||
switch (sortOrder) {
|
||||
case ASCENDING:
|
||||
sortIcon
|
||||
= UIManager.getIcon("Table.ascendingSortIcon");
|
||||
break;
|
||||
case DESCENDING:
|
||||
sortIcon
|
||||
= UIManager.getIcon("Table.descendingSortIcon");
|
||||
break;
|
||||
}
|
||||
|
||||
if (sortIcon != null)
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高,现注释掉!
|
||||
// contentBottom = sortIcon.getIconHeight();
|
||||
border = new IconBorder(sortIcon, contentTop, contentLeft,
|
||||
contentBottom, contentRight);
|
||||
else {
|
||||
sortIcon = UIManager.getIcon("Table.ascendingSortIcon");
|
||||
int sortIconHeight = (sortIcon != null) ? sortIcon.getIconHeight() : 0;
|
||||
if (sortIconHeight != 0) {
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高,现注释掉!
|
||||
// contentBottom = sortIconHeight;
|
||||
}
|
||||
border = new EmptyBorder(
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高,现注释掉!
|
||||
// sortIconHeight + contentTop, contentLeft, contentBottom, contentRight);
|
||||
// /现代码:border的top不要那么(原代码是为了仿vista的)
|
||||
contentTop, contentLeft, contentBottom, contentRight);
|
||||
}
|
||||
} else {
|
||||
contentTop += 3;
|
||||
border = new EmptyBorder(contentTop, contentLeft, contentBottom, contentRight);
|
||||
}
|
||||
setBorder(border);
|
||||
|
||||
//** jb2011设置字体颜色和加粗
|
||||
// this.setForeground(ColorHelper.DARK_GRAY1_LIKE_APPLE);
|
||||
// this.setFont(this.getFont().deriveFont(Font.BOLD));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Dimension size = getSize();
|
||||
// State state = State.NORMAL;
|
||||
// TableColumn draggedColumn = header.getDraggedColumn();
|
||||
// if (draggedColumn != null &&
|
||||
// column == SwingUtilities2.convertColumnIndexToView(
|
||||
// header.getColumnModel(),
|
||||
// draggedColumn.getModelIndex()))
|
||||
// {
|
||||
// state = State.PRESSED;
|
||||
// }
|
||||
// else if (isSelected || hasFocus || hasRollover)
|
||||
// {
|
||||
// state = State.HOT;
|
||||
// }
|
||||
/* on Vista there are more states for sorted columns */
|
||||
// if (WinUtils.isOnVista())
|
||||
// {
|
||||
// SortOrder sortOrder = getColumnSortOrder(header.getTable(), column);
|
||||
// if (sortOrder != null)
|
||||
// {
|
||||
// switch(sortOrder)
|
||||
// {
|
||||
// case ASCENDING:
|
||||
// /* falls through */
|
||||
// case DESCENDING:
|
||||
// switch (state)
|
||||
// {
|
||||
// case NORMAL:
|
||||
// state = State.SORTEDNORMAL;
|
||||
// break;
|
||||
// case PRESSED:
|
||||
// state = State.SORTEDPRESSED;
|
||||
// break;
|
||||
// case HOT:
|
||||
// state = State.SORTEDHOT;
|
||||
// break;
|
||||
// default:
|
||||
// /* do nothing */
|
||||
// }
|
||||
// default :
|
||||
// /* do nothing */
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
paintHeadCell(g, size);
|
||||
// skin.paintSkin(g, 0, 0, size.width-1, size.height-1, state);
|
||||
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
//* 由jb2011 修改自WindowsTableHeaderUI里的同名类.
|
||||
/**
|
||||
* A border with an Icon at the middle of the top side. Outer insets can be
|
||||
* provided for this border.
|
||||
*/
|
||||
private static class IconBorder implements Border, UIResource {
|
||||
|
||||
private final Icon icon;
|
||||
|
||||
private final int top, left, bottom, right;
|
||||
|
||||
public IconBorder(Icon icon, int top, int left, int bottom, int right) {
|
||||
this.icon = icon;
|
||||
this.top = top;
|
||||
this.left = left;
|
||||
this.bottom = bottom;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高,现注释掉!
|
||||
// return new Insets(icon.getIconHeight() + top, left, bottom, right);
|
||||
//现代码
|
||||
return new Insets(top, left, bottom, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
icon.paintIcon(c, g,
|
||||
//原UI代码:原代码里为了仿vista样式,标头高度很高且图标的位置是放在top中央,现注释掉!
|
||||
// x + left + (width - left - right - icon.getIconWidth()) / 2, y + top);
|
||||
|
||||
//现代码:图标放在右边利往左来2个像素的位置(好看一点)
|
||||
x + left + width - right - icon.getIconWidth() - 2, y);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETableUI.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.table;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
|
||||
/**
|
||||
* JTable的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BETableUI extends BasicTableUI {
|
||||
|
||||
UIDefaults defaultRenderersByColumnClass;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BETableUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize JTable properties, e.g. font, foreground, and background. The
|
||||
* font, foreground, and background properties are only set if their current
|
||||
* value is either null or a UIResource, other properties are set if the
|
||||
* current value is null.
|
||||
*
|
||||
* @see #installUI
|
||||
*/
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
super.installDefaults();
|
||||
//行高设置为25看起来会舒服些
|
||||
table.setRowHeight(25);
|
||||
//不显示垂直的网格线
|
||||
table.setShowVerticalLines(false);
|
||||
//设置单元格间的空白(默认是1个像素宽和高)
|
||||
//说明:设置本参数可以实现单元格间的间隔空制,间隔里通常是实现网格线的绘制,但
|
||||
//网格维绘制与否并不影响间隔的存在(如果间隔存在但网格线不绘的话它就是是透明的空
|
||||
//间),参数中width表示水平间隔,height表示垂直间隔,为0则表示没有间隔
|
||||
table.setIntercellSpacing(new Dimension(0, 1));
|
||||
LookAndFeel.installProperty(table, "opaque", Boolean.FALSE);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* FocusCellHighlightBorder.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.table;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
|
||||
/**
|
||||
* 表格单元获得焦点时的Border实现类.
|
||||
*
|
||||
* 本border由Jack Jiang实现,它是表格单元获得焦点时的边框(类似的功能在windows LNF下是一个距形虚线框)
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
class FocusCellHighlightBorder extends AbstractBorder {
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
// return new Insets(0,3,0,1);
|
||||
return new Insets(2, 2, 2, 2); // @since 3.5
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
return getBorderInsets(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
//* old impl
|
||||
// //在左边划一条2像素宽的竖线
|
||||
// g.setColor(UIManager.getColor("Table.focusCellHighlightBorderColor"));
|
||||
// g.fillRect(x, y, 2, height );//上下各空白一个像素,目的是为了与render的N9图片背景配合形成更好的视觉效果
|
||||
//
|
||||
// //再在上面的竖线右边划一条1像素宽的亮色竖线,以便为上面的2像素竖线营造立体效果
|
||||
// /* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性,目的是使Table.focusCellHighlightBorder有点立体效果哦 */
|
||||
// g.setColor(UIManager.getColor("Table.focusCellHighlightBorderHighlightColor"));
|
||||
// g.fillRect(x+2, y, 1, height );
|
||||
|
||||
//* @since 3.5
|
||||
BEUtils.draw4RecCorner(g, x, y, width - 2, height - 2, 5,
|
||||
UIManager.getColor("Table.focusCellHighlightBorderColor"));
|
||||
BEUtils.draw4RecCorner(g, x + 1, y + 1, width - 2, height - 2, 5,
|
||||
UIManager.getColor("Table.focusCellHighlightBorderHighlightColor"));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* TableScrollBorder.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.table;
|
||||
|
||||
import java.awt.Insets;
|
||||
|
||||
import org.jackhuang.hmcl.laf.widget.border.NinePatchBorder;
|
||||
|
||||
/**
|
||||
* 表格UI所在滚动条的边框实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-08-30
|
||||
* @version 1.0
|
||||
*/
|
||||
class TableScrollBorder extends NinePatchBorder {
|
||||
|
||||
public TableScrollBorder() {
|
||||
super(new Insets(3, 5, 10, 5), BETableHeaderUI.ICON_9.get("scroll_border"));
|
||||
}
|
||||
}
|
102
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/table/__UI__.java
Normal file
102
HMCLaF/src/main/java/org/jackhuang/hmcl/laf/table/__UI__.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.table;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
private static final IconFactory ICON = new IconFactory("table");
|
||||
|
||||
public static void uiImpl() {
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JTable的相关ui属性设定
|
||||
//JTable所属的滚动面板的border实现(不像JList,JTable的UI自动为它配备的一个JScrollPane)
|
||||
put("Table.scrollPaneBorder", new TableScrollBorder());//defaut is com.sun.java.swing.plaf.windows.XPStyle.XPFillBorder
|
||||
put("Table.focusCellHighlightBorder", new FocusCellHighlightBorder());//new BEDashedBorder(new Color(0,160,0),1,0,true,false,true,false)));
|
||||
/* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性 */
|
||||
put("Table.focusCellHighlightBorderColor", Color.white);//new ColorUIResource(Color.red));
|
||||
/* ~~注:这个属性是jb2011为了更好的ui效果自已加的属性,目的是使Table.focusCellHighlightBorder有点立体效果哦 */
|
||||
putColor("Table.focusCellHighlightBorderHighlightColor", 255, 255, 255, 70);//注意:这个颜色是半透明的哦
|
||||
put("Table.background", Color.white);
|
||||
//** 2011-03-16 add by jb2011 为了使JDK1.6及以上表格头在排序时能显示排序箭头(1.6里的排序图标是在UI里设定的)
|
||||
UIManager.put("Table.descendingSortIcon", ICON.get("descending_sort"));
|
||||
UIManager.put("Table.ascendingSortIcon", ICON.get("ascending_sort"));
|
||||
put("Table.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
putColor("Table.gridColor", 220, 220, 220);
|
||||
put("Table.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("Table.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("TableUI", BETableUI.class);
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JTable表头相关ui属性设定
|
||||
// UIManager.put("TableHeader.font",new Font("宋体",Font.PLAIN,12));//此属性将决定表头的字体
|
||||
put("TableHeader.background", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("TableHeader.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
|
||||
//不建议完全定制表头ui,因为BasicTableHeaderUI里的关键方法都是private,无法继承重写,要实现自已
|
||||
//的绘制逻辑需要重写大段代码,而因JTable在不同jdk版本里的变动较大:比如1.6里才有的排序(及图标)及相关方法
|
||||
//在不同的版本里都不尽相同,而且调用了若干sun的非公开包里的api。虽存在兼容性问题,为了UI美观,还是自定义实现吧
|
||||
put("TableHeaderUI", BETableHeaderUI.class);
|
||||
//** BE LNF的本属性只在Java版本高于1.5时起效
|
||||
//* 由jb2011自已加的属性,因原BasicTableHeaderUI里用TableHeader.cellBorder来设置
|
||||
//border,但WindowsTableHeaderUI的border则是自已实现的IconBorder,而BE LNF中则是仿
|
||||
//照Windows LNF实现,所以只能实现一个自已的属性来供以后的使用者灵活设定(否则只能像Windows LNF一样硬编码在代码里)
|
||||
putInsets("TableHeader.cellMargin", 7, 0, 7, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Border for a Table Header.
|
||||
*
|
||||
* @see javax.swing.plaf.metal.TableHeaderBorder
|
||||
*/
|
||||
public static class TableHeaderBorder extends javax.swing.border.AbstractBorder {
|
||||
|
||||
protected Insets editorBorderInsets = new Insets(7, 0, 7, 0);//默认是2, 2, 2, 0 );
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
|
||||
g.translate(x, y);
|
||||
|
||||
// g.setColor(MetalLookAndFeel.getControlDarkShadow() );
|
||||
// g.drawLine( w-1, 0, w-1, h-1 );
|
||||
// g.drawLine( 1, h-1, w-1, h-1 );
|
||||
// g.setColor( MetalLookAndFeel.getControlHighlight() );
|
||||
// g.drawLine( 0, 0, w-2, 0 );
|
||||
// g.drawLine( 0, 0, 0, h-2 );
|
||||
//* add by Jack Jiang START
|
||||
//绘制表头单元的底部水平线(跟网格线颜色一样就可以了)
|
||||
g.setColor(UIManager.getColor("Table.gridColor"));
|
||||
g.drawLine(0, h - 1, w, h - 1);
|
||||
|
||||
//绘制表头单元的右分隔竖线
|
||||
BETableHeaderUI.ICON_9.get("header_cell_separator")
|
||||
.draw((Graphics2D) g, w - 4, 0, 4, h);
|
||||
//* add by Jack Jiang END
|
||||
|
||||
g.translate(-x, -y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return editorBorderInsets;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEEditorPaneUI.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JEditorPane的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-08-25
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsEditorPaneUI
|
||||
*/
|
||||
public class BEEditorPaneUI extends BasicEditorPaneUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
//默认是纯白色背景,因为JEditorPane肯定是要放在JScrollPane中的,而ScrollPane也是有边框的
|
||||
//如果JEditorPane再有边框就很难看了,所以JEditorPane在没有获得焦点时就已无边框效果出现会好看很多
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("white");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
BETextFieldUI.addOtherListener(c);
|
||||
// c.addMouseListener(new NLLookAndFeel.EditMenu());
|
||||
return new BEEditorPaneUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JEditorPane的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JEditorPane.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g); // TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
|
||||
// /**
|
||||
// * Creates the object to use for a caret. By default an
|
||||
// * instance of WindowsCaret is created. This method
|
||||
// * can be redefined to provide something else that implements
|
||||
// * the InputPosition interface or a subclass of DefaultCaret.
|
||||
// *
|
||||
// * @return the caret object
|
||||
// */
|
||||
// protected Caret createCaret() {
|
||||
// return new WindowsTextUI.WindowsCaret();
|
||||
// }
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEPasswordFieldUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicFormattedTextFieldUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JFormattedTextField的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2015-11-13
|
||||
* @since 3.7
|
||||
*/
|
||||
public class BEFormattedTextFieldUI extends BasicFormattedTextFieldUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("normal");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
c.addFocusListener(FocusListenerImpl.getInstance());
|
||||
return new BEFormattedTextFieldUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JPasswordField的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JPasswordField.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g);// TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEPasswordFieldUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicPasswordFieldUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JPasswordField的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BEPasswordFieldUI extends BasicPasswordFieldUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("normal");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
c.addFocusListener(FocusListenerImpl.getInstance());
|
||||
// c.addMouseListener(new NLLookAndFeel.EditMenu());
|
||||
return new BEPasswordFieldUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JPasswordField的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JPasswordField.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g);// TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETextAreaUI.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextAreaUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JTextArea的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BETextAreaUI extends BasicTextAreaUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported//WindowsTextAreaUI
|
||||
{
|
||||
//默认是纯白色背景,因为JTextArea肯定是要放在JScrollPane中的,而ScrollPane也是有边框的
|
||||
//如果JTextArea再有边框就很难看了,所以JTextArea在没有获得焦点时就已无边框效果出现会好看很多
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("white");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
BETextFieldUI.addOtherListener(c);
|
||||
// c.addMouseListener(new NLLookAndFeel.EditMenu());
|
||||
return new BETextAreaUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JTextField的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JTextField.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g);// TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETextFieldUI.java at 2015-2-1 20:25:37, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JTextField的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class BETextFieldUI extends BasicTextFieldUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("normal");
|
||||
|
||||
public static BETextFieldUI createUI(JComponent c) {
|
||||
addOtherListener(c);
|
||||
return new BETextFieldUI();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JTextField的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JTextField.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
// Color bgc = editor.getBackground();
|
||||
// g.setColor(bgc);
|
||||
// //先填 充背景
|
||||
// g.fillRect(0, 0, editor.getWidth(), editor.getHeight());
|
||||
//
|
||||
// //(1) ---- 仿Numbus文本框效果
|
||||
// //** top立体效果实现
|
||||
// //第(0,0)开始的第一条线会被后来的border覆盖掉的,所以此处绘制没有意义,不搞了
|
||||
//// g.setColor(new Color(0,0,0));
|
||||
//// g.drawLine(0, 0, editor.getWidth(), 0);
|
||||
// //第2条线颜色淡一点
|
||||
// g.setColor(new Color(208,208,208));
|
||||
// g.drawLine(0, 1, editor.getWidth(), 1);
|
||||
// //第3条线颜色更淡一点
|
||||
// g.setColor(new Color(231,231,225));
|
||||
// g.drawLine(0, 2, editor.getWidth(), 2);
|
||||
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g);// TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
|
||||
// if(this.getComponent().isEnabled())
|
||||
// //*** 重要说明:因使用的NinePatch图片作填充背景,所以后绪任何对JTextField设置
|
||||
// //*** 背景色将不会起效,因为背景是用图片填充而非传统方法绘制出来的
|
||||
// bg.draw((Graphics2D)g, 0, 0, editor.getWidth(), editor.getHeight());
|
||||
// else
|
||||
// __Icon9Factory__.getInstance().getTextFieldBgDisabled()
|
||||
// .draw((Graphics2D)g, 0, 0, editor.getWidth(), editor.getHeight());
|
||||
//// //(2) ---- 仿360软件管家文本框效果(不太好看)
|
||||
// //** top立体效果实现
|
||||
// //第(0,0)开始的第一条线会被后来的border覆盖掉的,所以此处绘制没有意义,不搞了
|
||||
//// g.setColor(new Color(0,0,0));
|
||||
//// g.drawLine(0, 0, editor.getWidth(), 0);
|
||||
// //第2条线颜色淡一点
|
||||
// g.setColor(new Color(232,232,232));
|
||||
// g.drawLine(1, 1, editor.getWidth()-1, 1);
|
||||
// //第3条线颜色更淡一点
|
||||
// g.setColor(new Color(241,241,241));
|
||||
// g.drawLine(1, 2, editor.getWidth()-1, 2);
|
||||
// //第4条线颜色更淡一点
|
||||
// g.setColor(new Color(248,248,248));
|
||||
// g.drawLine(1, 3, editor.getWidth()-1, 3);
|
||||
// //第5条线颜色更淡一点
|
||||
// g.setColor(new Color(252,252,252));
|
||||
// g.drawLine(1, 4, editor.getWidth()-1, 4);
|
||||
//
|
||||
// //** left
|
||||
// //第2条线颜色淡一点
|
||||
// g.setColor(new Color(241,241,241));
|
||||
// g.drawLine(1, 1, 1, editor.getHeight()-1);
|
||||
// //第3条线颜色淡一点
|
||||
// g.setColor(new Color(248,248,248));
|
||||
// g.drawLine(2, 1, 2, editor.getHeight()-1);
|
||||
// //第4条线颜色淡一点
|
||||
// g.setColor(new Color(253,253,253));
|
||||
// g.drawLine(3, 1, 3, editor.getHeight()-1);
|
||||
//
|
||||
// //** right
|
||||
// //第2条线颜色淡一点
|
||||
// g.setColor(new Color(241,241,241));
|
||||
// g.drawLine(editor.getWidth()-1, 1, editor.getWidth()-1, editor.getHeight()-1);
|
||||
// //第3条线颜色淡一点
|
||||
// g.setColor(new Color(248,248,248));
|
||||
// g.drawLine(editor.getWidth()-2, 1, editor.getWidth()-2, editor.getHeight()-1);
|
||||
// //第4条线颜色淡一点
|
||||
// g.setColor(new Color(253,253,253));
|
||||
// g.drawLine(editor.getWidth()-3, 1, editor.getWidth()-3, editor.getHeight()-1);
|
||||
//
|
||||
// //** bottom
|
||||
// //第2条线颜色淡一点
|
||||
// g.setColor(new Color(248,248,248));
|
||||
// g.drawLine(1, editor.getHeight()-1, editor.getWidth()-1, editor.getHeight()-1);
|
||||
// //第3条线颜色淡一点
|
||||
// g.setColor(new Color(252,252,252));
|
||||
// g.drawLine(1, editor.getHeight()-2, editor.getWidth()-1, editor.getHeight()-2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
|
||||
/**
|
||||
* Paint bg.
|
||||
*
|
||||
* @param g the g
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param w the w
|
||||
* @param h the h
|
||||
* @param enabled the enabled
|
||||
* @param bg the bg
|
||||
*/
|
||||
public static void paintBg(Graphics g, int x, int y, int w, int h,
|
||||
boolean enabled, Color border) {
|
||||
if (enabled) {
|
||||
g.setColor(border);
|
||||
g.fillRect(x, y, w, h);
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(x + 2, y + 2, w - 4, h - 4);
|
||||
}
|
||||
else
|
||||
__UI__.ICON_9.get("disabled")
|
||||
.draw((Graphics2D) g, x, y, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为组件添加焦点监听器(获得/取消焦点时可以自动设置/取消一个彩色的边框效果,以体高UI体验) 、右键菜单监听器(有复制/粘贴等功能).
|
||||
*
|
||||
* @param c the c
|
||||
*/
|
||||
public static void addOtherListener(JComponent c) {
|
||||
c.addFocusListener(FocusListenerImpl.getInstance());
|
||||
c.addMouseListener(FocusListenerImpl.getInstance());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BETextPaneUI.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicTextPaneUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* 文本组件JTextPane的UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com), 2012-08-25
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsTextPaneUI
|
||||
*/
|
||||
public class BETextPaneUI extends BasicTextPaneUI implements BgSwitchable,
|
||||
org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
//默认是纯白色背景,因为JTextPane肯定是要放在JScrollPane中的,而ScrollPane也是有边框的
|
||||
//如果JTextPane再有边框就很难看了,所以JTextPane在没有获得焦点时就已无边框效果出现会好看很多
|
||||
|
||||
private NinePatch bg = __UI__.ICON_9.get("white");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
BETextFieldUI.addOtherListener(c);
|
||||
// c.addMouseListener(new NLLookAndFeel.EditMenu());
|
||||
return new BETextPaneUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,边框和背景等都是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制JTextPane的颜色和边框,本方法的目的就是当用户设置了进度条的border或背景色 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JTextPane.setUI(..)方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return getComponent() != null
|
||||
&& (!(getComponent().getBorder() instanceof UIResource)
|
||||
|| !(getComponent().getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a background for the view. This will only be called if isOpaque()
|
||||
* on the associated component is true. The default is to paint the
|
||||
* background color of the component.
|
||||
*
|
||||
* @param g the graphics context
|
||||
*/
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
//先调用父类方法把背景刷新下(比如本UI里使用的大圆角NP图如不先刷新背景则会因上下拉动滚动条
|
||||
//而致4个圆角位置得不到刷新,从而影响视觉效果(边角有前面的遗留),置于透明边角不被透明像素填
|
||||
//充的问题,它有可能是Android的NinePatch技术为了性能做作出的优化——一切全透明像素即意味着不需绘制)
|
||||
super.paintBackground(g);// TODO 出于节约计算资源考生虑,本行代码换成父类中默认填充背景的代码即可
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (!isUseParentPaint()) {
|
||||
//用新的NP图实现真正的背景填充
|
||||
JTextComponent editor = this.getComponent();
|
||||
BETextFieldUI.paintBg(g, 0, 0, editor.getWidth(), editor.getHeight(),
|
||||
editor.isEnabled(), border);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToNormal() {
|
||||
border = __UI__.BORDER_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToFocused() {
|
||||
border = __UI__.border_focused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchBgToOver() {
|
||||
border = __UI__.BORDER_OVER;
|
||||
}
|
||||
|
||||
Color border = __UI__.BORDER_NORMAL;
|
||||
|
||||
// /**
|
||||
// * Creates the object to use for a caret. By default an
|
||||
// * instance of WindowsCaret is created. This method
|
||||
// * can be redefined to provide something else that implements
|
||||
// * the InputPosition interface or a subclass of DefaultCaret.
|
||||
// *
|
||||
// * @return the caret object
|
||||
// */
|
||||
// protected Caret createCaret() {
|
||||
// return new WindowsTextUI.WindowsCaret();
|
||||
// }
|
||||
}
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* FocusListenerImpl.java at 2015-2-1 20:25:40, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jackhuang.hmcl.laf.textcoms.__UI__.BgSwitchable;
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.widget.border.BERoundBorder;
|
||||
|
||||
/**
|
||||
* 焦点改变时的监听器实现类.
|
||||
* <p>
|
||||
* 目前主要用于各文本组件.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
*/
|
||||
public class FocusListenerImpl implements FocusListener, MouseListener {
|
||||
|
||||
/**
|
||||
* 文本组件等获得焦点后的边框线条宽度.
|
||||
*/
|
||||
public static int defaultFocusedThikness = 2;
|
||||
|
||||
/**
|
||||
* Gets the single instance of FocusListenerImpl.
|
||||
*
|
||||
* @return single instance of FocusListenerImpl
|
||||
*/
|
||||
public static FocusListenerImpl getInstance() {
|
||||
// return INSTANCE;
|
||||
return new FocusListenerImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* The focused thikness.
|
||||
*/
|
||||
protected int focusedThikness = defaultFocusedThikness;
|
||||
|
||||
/**
|
||||
* Gets the focused thikness.
|
||||
*
|
||||
* @return the focused thikness
|
||||
*/
|
||||
public int getFocusedThikness() {
|
||||
return focusedThikness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focused thikness.
|
||||
*
|
||||
* @param focusedThikness the focused thikness
|
||||
* @return the focus listener impl
|
||||
*/
|
||||
public FocusListenerImpl setFocusedThikness(int focusedThikness) {
|
||||
this.focusedThikness = focusedThikness;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (e.getSource() instanceof JComponent) {
|
||||
JComponent com = (JComponent) e.getSource();
|
||||
Border orignalBorder = com.getBorder();
|
||||
|
||||
if (orignalBorder != null) {
|
||||
//决定获得焦点时的连框色调
|
||||
Color focusedColor = getTextFieldFocusedColor();
|
||||
|
||||
//JTextField获得焦点时特殊处理:自动切换它的背景图即可(用NinePatch图实现)
|
||||
if (com instanceof JTextComponent) {
|
||||
JTextComponent text = (JTextComponent) com;
|
||||
ComponentUI ui = text.getUI();
|
||||
text.putClientProperty("BEFocused", true);
|
||||
if (ui instanceof BgSwitchable) {
|
||||
((BgSwitchable) ui).switchBgToFocused();
|
||||
com.repaint();
|
||||
return;
|
||||
}
|
||||
} else if (com instanceof JComboBox)
|
||||
focusedColor = getComboBoxFocusedColor();
|
||||
|
||||
//获得焦点后的新边框
|
||||
BERoundBorder cc;
|
||||
if (orignalBorder instanceof BERoundBorder)
|
||||
cc = (BERoundBorder) (((BERoundBorder) orignalBorder).clone());
|
||||
else
|
||||
cc = new BERoundBorder(1).setArcWidth(0);
|
||||
cc.setLineColor(focusedColor);
|
||||
cc.setThickness(focusedThikness);
|
||||
|
||||
//* !当组件是JPasswordField,它的反应会有bug,也就是在setBorder之后它的
|
||||
//* preferredSize会变的很小,这里针对其作的特殊处理就是为了使其size与setBorder前保持一致
|
||||
Dimension oldDm = null;
|
||||
if (com instanceof JTextField)
|
||||
oldDm = com.getSize();
|
||||
com.setBorder(cc);
|
||||
if (com instanceof JTextField)
|
||||
com.setPreferredSize(oldDm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (e.getSource() instanceof JComponent) {
|
||||
JComponent com = (JComponent) e.getSource();
|
||||
|
||||
//JTextField获得焦点时特殊处理:自动切换它的背景图即可(用NinePatch图实现)
|
||||
if (com instanceof JTextComponent) {
|
||||
JTextComponent text = (JTextComponent) com;
|
||||
ComponentUI ui = text.getUI();
|
||||
text.putClientProperty("BEFocused", false);
|
||||
if (ui instanceof BgSwitchable) {
|
||||
((BgSwitchable) ui).switchBgToNormal();
|
||||
com.repaint();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//失去焦点时还原边框样式
|
||||
Border orignalBorder = com.getBorder();
|
||||
if (orignalBorder != null)
|
||||
if (orignalBorder instanceof BERoundBorder) {
|
||||
BERoundBorder cc = (BERoundBorder) (((BERoundBorder) orignalBorder).clone());
|
||||
cc.setLineColor(BERoundBorder.defaultLineColor);
|
||||
cc.setThickness(1);
|
||||
com.setBorder(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text field focused color.
|
||||
*
|
||||
* @return the text field focused color
|
||||
*/
|
||||
public static Color getTextFieldFocusedColor() {
|
||||
return BEUtils.getColor(UIManager.getColor("TextField.selectionBackground"), 30, 30, 30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the combo box focused color.
|
||||
*
|
||||
* @return the combo box focused color
|
||||
*/
|
||||
public static Color getComboBoxFocusedColor() {
|
||||
return BEUtils.getColor(UIManager.getColor("ComboBox.selectionBackground"), 30, 30, 30);
|
||||
}
|
||||
// public static Color getTextPaneFocusedColor()
|
||||
// {
|
||||
// return LNFUtils.getColor(UIManager.getColor("TextPane.selectionBackground"),30,30,30);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (e.getSource() instanceof JComponent) {
|
||||
JComponent com = (JComponent) e.getSource();
|
||||
|
||||
//JTextField获得焦点时特殊处理:自动切换它的背景图即可(用NinePatch图实现)
|
||||
if (com instanceof JTextComponent) {
|
||||
JTextComponent text = (JTextComponent) com;
|
||||
ComponentUI ui = text.getUI();
|
||||
Object o = text.getClientProperty("BEFocused");
|
||||
if (o == null || o == Boolean.FALSE)
|
||||
if (ui instanceof BgSwitchable) {
|
||||
((BgSwitchable) ui).switchBgToOver();
|
||||
com.repaint();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//失去焦点时还原边框样式
|
||||
Border orignalBorder = com.getBorder();
|
||||
if (orignalBorder != null)
|
||||
if (orignalBorder instanceof BERoundBorder) {
|
||||
BERoundBorder cc = (BERoundBorder) (((BERoundBorder) orignalBorder).clone());
|
||||
cc.setLineColor(BERoundBorder.defaultLineColor);
|
||||
cc.setThickness(1);
|
||||
com.setBorder(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
if (e.getSource() instanceof JComponent) {
|
||||
JComponent com = (JComponent) e.getSource();
|
||||
|
||||
//JTextField获得焦点时特殊处理:自动切换它的背景图即可(用NinePatch图实现)
|
||||
if (com instanceof JTextComponent) {
|
||||
JTextComponent text = (JTextComponent) com;
|
||||
ComponentUI ui = text.getUI();
|
||||
Object o = text.getClientProperty("BEFocused");
|
||||
if (o == null || o == Boolean.FALSE)
|
||||
if (ui instanceof BgSwitchable) {
|
||||
((BgSwitchable) ui).switchBgToNormal();
|
||||
com.repaint();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//失去焦点时还原边框样式
|
||||
Border orignalBorder = com.getBorder();
|
||||
if (orignalBorder != null)
|
||||
if (orignalBorder instanceof BERoundBorder) {
|
||||
BERoundBorder cc = (BERoundBorder) (((BERoundBorder) orignalBorder).clone());
|
||||
cc.setLineColor(BERoundBorder.defaultLineColor);
|
||||
cc.setThickness(1);
|
||||
com.setBorder(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:38, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.textcoms;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
import org.jackhuang.hmcl.laf.widget.border.BERoundBorder;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
static final Color BORDER_NORMAL = GraphicsUtils.getWebColor("#999999");
|
||||
static final Color BORDER_OVER = GraphicsUtils.getWebColor("#666666");
|
||||
|
||||
static Color border_focused() {
|
||||
return (Color) UIManager.get("TextField.focused");
|
||||
}
|
||||
|
||||
public static final Icon9Factory ICON_9 = new Icon9Factory("text");
|
||||
|
||||
public static void uiImpl() {
|
||||
final InsetsUIResource iuir = new InsetsUIResource(4, 7, 4, 7);
|
||||
final BERoundBorder berb = new BERoundBorder().setLineColor(new Color(0, 0, 0, 0));
|
||||
|
||||
//使用全透明色绘边框(用什么边框无所谓,关键是读取它的margin并透明),目的就是要让它的背景显现出来(NinePatch图实现)
|
||||
UIManager.put("TextField.margin", iuir);
|
||||
put("TextField.border", berb);
|
||||
put("TextField.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("TextField.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("TextField.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("TextFieldUI", BETextFieldUI.class);
|
||||
|
||||
UIManager.put("FormattedTextField.margin", iuir);
|
||||
put("FormattedTextField.border", new BERoundBorder(1).setArcWidth(10).setLineColor(new Color(0, 0, 0, 0)));
|
||||
put("FormattedTextField.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("FormattedTextField.inactiveBackground", BeautyEyeLNFHelper.commonBackgroundColor);
|
||||
put("FormattedTextField.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("FormattedTextField.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("FormattedTextFieldUI", BEFormattedTextFieldUI.class);
|
||||
|
||||
UIManager.put("PasswordField.margin", iuir);
|
||||
put("PasswordField.border", berb);
|
||||
put("PasswordField.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("PasswordField.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("PasswordField.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("PasswordFieldUI", BEPasswordFieldUI.class);
|
||||
|
||||
UIManager.put("TextArea.margin", iuir);
|
||||
put("TextArea.border", berb);
|
||||
put("TextArea.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("TextArea.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("TextArea.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("TextAreaUI", BETextAreaUI.class);
|
||||
|
||||
put("TextPane.border", berb);
|
||||
put("TextPane.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("TextPane.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("TextPane.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("TextPaneUI", BETextPaneUI.class);
|
||||
|
||||
put("EditorPane.border", berb);
|
||||
put("EditorPane.selectionForeground", BeautyEyeLNFHelper.commonSelectionForegroundColor);
|
||||
put("EditorPane.selectionBackground", BeautyEyeLNFHelper.commonSelectionBackgroundColor);
|
||||
put("EditorPane.foreground", BeautyEyeLNFHelper.commonForegroundColor);
|
||||
put("EditorPaneUI", BEEditorPaneUI.class);
|
||||
}
|
||||
|
||||
public interface BgSwitchable {
|
||||
|
||||
void switchBgToNormal();
|
||||
|
||||
void switchBgToFocused();
|
||||
|
||||
void switchBgToOver();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* __UI__.java at 2015-2-1 20:25:39, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.titlepane;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.BorderUIResource;
|
||||
|
||||
import org.jackhuang.hmcl.laf.BeautyEyeLNFHelper;
|
||||
import org.jackhuang.hmcl.laf.BEUtils;
|
||||
import org.jackhuang.hmcl.laf.utils.IconFactory;
|
||||
import org.jackhuang.hmcl.laf.utils.UI;
|
||||
|
||||
public class __UI__ extends UI {
|
||||
|
||||
protected static final IconFactory ICON = new IconFactory("frame");
|
||||
|
||||
public static void uiImpl() {
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 窗体ui的各项属性设定
|
||||
//*~ 本属性是Jack Jiang自已设定的,Java的Metal主题默认对非Frame对象的窗口图标取的是InternalFrame.icon,这是不对的
|
||||
UIManager.put("Frame.icon", ICON.get("icon"));
|
||||
|
||||
UIManager.put("Frame.iconifyIcon", ICON.get("iconify"));
|
||||
UIManager.put("Frame.iconifyIcon_rover", ICON.get("iconify_over"));
|
||||
UIManager.put("Frame.iconifyIcon_pressed", ICON.get("iconify_pressed"));
|
||||
|
||||
UIManager.put("Frame.minimizeIcon", ICON.get("min"));
|
||||
UIManager.put("Frame.minimizeIcon_rover", ICON.get("min_over"));
|
||||
UIManager.put("Frame.minimizeIcon_pressed", ICON.get("min_pressed"));
|
||||
|
||||
UIManager.put("Frame.maximizeIcon", ICON.get("max"));
|
||||
UIManager.put("Frame.maximizeIcon_rover", ICON.get("max_over"));
|
||||
UIManager.put("Frame.maximizeIcon_pressed", ICON.get("max_pressed"));
|
||||
|
||||
UIManager.put("Frame.closeIcon", ICON.get("close"));
|
||||
UIManager.put("Frame.closeIcon_rover", ICON.get("close_over"));
|
||||
UIManager.put("Frame.closeIcon_pressed", ICON.get("close_pressed"));
|
||||
|
||||
//设定用于演示之用的“设置”按钮图标
|
||||
UIManager.put("Frame.setupIcon", ICON.get("setup"));
|
||||
|
||||
// put("activeCaption", Windows2LookAndFeel.activeCaption);
|
||||
put("activeCaptionText", BeautyEyeLNFHelper.activeCaptionTextColor);
|
||||
// put("activeCaptionBorder", Windows2LookAndFeel.activeCaptionBorder);
|
||||
// put("inactiveCaption", GraphicHandler.getColor(activeCaption, 64, 42, 22));
|
||||
put("inactiveCaptionText", BEUtils.getColor(BeautyEyeLNFHelper.activeCaptionTextColor, -49, -27, -7));
|
||||
// put("inactiveCaptionBorder", GraphicHandler.getColor(activeCaptionBorder, 64, 42, 22));
|
||||
|
||||
//此属性即是BeautyEye LNF的窗口标题栏实现
|
||||
put("RootPaneUI", BERootPaneUI.class);
|
||||
|
||||
// These bindings are only enabled when there is a default
|
||||
// button set on the rootpane.
|
||||
UIManager.put("RootPane.defaultButtonWindowKeyBindings", new Object[] {
|
||||
"ENTER", "press",
|
||||
"released ENTER", "release",
|
||||
"ctrl ENTER", "press",
|
||||
"ctrl released ENTER", "release"
|
||||
});
|
||||
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OptionPane的各项ui属性设定
|
||||
Object dialogBorder = new BorderUIResource(BeautyEyeLNFHelper.getFrameBorder());//BorderFactory.createLineBorder(new Color(181,181,181)));
|
||||
UIManager.put("RootPane.frameBorder", dialogBorder);
|
||||
UIManager.put("RootPane.plainDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.informationDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.errorDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.colorChooserDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.fileChooserDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.questionDialogBorder", dialogBorder);
|
||||
UIManager.put("RootPane.warningDialogBorder", dialogBorder);
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEToolBarSeparatorUI.java at 2015-2-1 20:25:36, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.toolbar;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Stroke;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
|
||||
|
||||
/**
|
||||
* JToolBar的分隔条UI实现类.
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsToolBarSeparatorUI
|
||||
*/
|
||||
public class BEToolBarSeparatorUI extends BasicToolBarSeparatorUI {
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEToolBarSeparatorUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
Dimension size = ((JToolBar.Separator) c).getSeparatorSize();
|
||||
|
||||
if (size != null)
|
||||
size = size.getSize();
|
||||
else {
|
||||
size = new Dimension(6, 6);
|
||||
|
||||
if (((JSeparator) c).getOrientation() == SwingConstants.VERTICAL)
|
||||
size.height = 0;
|
||||
else
|
||||
size.width = 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize(JComponent c) {
|
||||
Dimension pref = getPreferredSize(c);
|
||||
if (((JSeparator) c).getOrientation() == SwingConstants.VERTICAL)
|
||||
return new Dimension(pref.width, Short.MAX_VALUE);
|
||||
else
|
||||
return new Dimension(Short.MAX_VALUE, pref.height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
boolean vertical = ((JSeparator) c).getOrientation() == SwingConstants.VERTICAL;
|
||||
Dimension size = c.getSize();
|
||||
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);//
|
||||
|
||||
Color temp = g.getColor();
|
||||
UIDefaults table = UIManager.getLookAndFeelDefaults();
|
||||
Color shadow = table.getColor("ToolBar.shadow");
|
||||
Color highlight = table.getColor("ToolBar.highlight");
|
||||
|
||||
// TODO BUG_001:不知何故,垂直分隔条并不能像水平分隔条一样,拥有默认设置的new Dimension(6, 6)
|
||||
// 而只有new Dimension(1, ...),而当它floating时却能正常表现(只能绘出hilight而不能绘出shadow)
|
||||
//,有待深入研究,垂直的分隔条则不会有此种情况
|
||||
if (vertical) {
|
||||
int x = (size.width / 2) - 1;
|
||||
|
||||
//* 当BUG_001存在时,暂时使用以下代码解决:把本该显示hilight的
|
||||
//* 线条用shadow颜色绘制,最大可能保证ui的正常展现
|
||||
// g.setColor(shadow);
|
||||
// g.drawLine(x, 2, x, size.height - 2);
|
||||
g.setColor(shadow);//highlight);
|
||||
g.drawLine(x + 1, 2, x + 1, size.height - 2);
|
||||
|
||||
//* 当BUG_001不存在时,应该使用以下代码
|
||||
// g.setColor(shadow);
|
||||
// g.drawLine(x, 2, x, size.height - 2);
|
||||
// g.setColor(highlight);
|
||||
// g.drawLine(x + 1, 2, x + 1, size.height - 2);
|
||||
} else {
|
||||
int y = (size.height / 2) - 1;
|
||||
g.setColor(shadow);
|
||||
g.drawLine(2, y, size.width - 2, y);
|
||||
|
||||
g.setColor(highlight);
|
||||
g.drawLine(2, y + 1, size.width - 2, y + 1);
|
||||
}
|
||||
g.setColor(temp);
|
||||
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jack Jiang(cngeeker.com) The BeautyEye Project.
|
||||
* All rights reserved.
|
||||
* Project URL:https://github.com/JackJiang2011/beautyeye
|
||||
* Version 3.6
|
||||
*
|
||||
* Jack Jiang PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
* BEToolBarUI.java at 2015-2-1 20:25:41, original version by Jack Jiang.
|
||||
* You can contact author with jb2011@163.com.
|
||||
*/
|
||||
package org.jackhuang.hmcl.laf.toolbar;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.ContainerListener;
|
||||
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicToolBarUI;
|
||||
|
||||
import org.jackhuang.hmcl.laf.button.BEButtonUI;
|
||||
import org.jackhuang.hmcl.laf.utils.Icon9Factory;
|
||||
import org.jb2011.ninepatch4j.NinePatch;
|
||||
|
||||
/**
|
||||
* JToolBar的UI实现类。
|
||||
*
|
||||
* <p>
|
||||
* <b>Since v3.4:</b><br>
|
||||
* 可以使用"ToolBar.isPaintPlainBackground"来控制BEToolBarUI还是
|
||||
* 默认的渐变NinePatch图实现背景的填充(效果好,但是背景比较强烈,不适于组件密集的场景).
|
||||
* 全局控制可以通过UIManager.put("ToolBar.isPaintPlainBackground",
|
||||
* Boolean.FALSE)(UIManager中默认是false)
|
||||
* 或者通过JToolBar.putClientProperty("ToolBar.isPaintPlainBackground",
|
||||
* Boolean.FALSE) 独立控制,ClientProperty中的设置拥有最高优先级。
|
||||
*
|
||||
* 特别说明:JToolBar比较特殊,加入到JToolBar中的组件,其UI(主要是Border)将由ToolBarUI额
|
||||
* 外控制而不受自身UI控制,比如放入到JToolBar中的JToggleButton,它的border就是受ToolBarUI
|
||||
* 控制,这些JToggleButton将无论如何修改ToolgleButtonUI.border也不会起效。
|
||||
*
|
||||
* @author Jack Jiang(jb2011@163.com)
|
||||
* @see com.sun.java.swing.plaf.windows.WindowsToolBarUI
|
||||
*/
|
||||
public class BEToolBarUI extends BasicToolBarUI
|
||||
implements org.jackhuang.hmcl.laf.BeautyEyeLNFHelper.__UseParentPaintSurported {
|
||||
|
||||
private static final Icon9Factory ICON_9 = new Icon9Factory("toolbar");
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new BEToolBarUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installDefaults() {
|
||||
setRolloverBorders(true);
|
||||
super.installDefaults();
|
||||
}
|
||||
|
||||
//* 本方法由Jack Jiang于2012-09-07日加入
|
||||
/**
|
||||
* 是否使用父类的绘制实现方法,true表示是.
|
||||
* <p>
|
||||
* 因为在BE LNF中,工具条背景是使用N9图,没法通过设置背景色和前景
|
||||
* 色来控制工具条的颜色,本方法的目的就是当用户设置了工具条的Background 时告之本实现类不使用BE
|
||||
* LNF中默认的N9图填充绘制而改用父类中的方法(父类中的方法 就可以支持颜色的设置罗,只是丑点,但总归是能适应用户的需求场景要求,其实用户完全可以
|
||||
* 通过JToolBar.setUI(new MetalToolBar())等方式来自定义UI哦).
|
||||
*
|
||||
* @return true, if is use parent paint
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseParentPaint() {
|
||||
return toolBar != null
|
||||
&& (!(toolBar.getBackground() instanceof UIResource));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Border createRolloverBorder() {
|
||||
return new EmptyBorder(3, 3, 3, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Border createNonRolloverBorder() {
|
||||
return new EmptyBorder(3, 3, 3, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
//~* @since 3.4, add by Jack Jiang 2012-11-05
|
||||
//~* 【BeautyEye外观的特有定制属性】:true表示BEToolBarUI里,将使用其它典型外观
|
||||
//~* 一样的默认纯色填充背景(颜色由ToolBar.background属性指定), 否则将使用BeautyEye
|
||||
//~* 默认的渐变NinePatch图实现背景的填充。另外,还可以使用
|
||||
//~* JToolBar.putClientProperty("ToolBar.isPaintPlainBackground", Boolean.TRUE);来进行
|
||||
//~* 独立控制背景的填充方法,ClientProperty相比UIManager中的本方法拥有最高优先级
|
||||
boolean isPaintPlainBackground = false;
|
||||
String isPaintPlainBackgroundKey = "ToolBar.isPaintPlainBackground";//~* 【BeautyEye外观的特有定制属性】@since 3.4
|
||||
//首先看看有没有独立在ClientProperty中设置"ToolBar.isPaintPlainBackground"属性(ClientProperty中设置拥有最高优先级)
|
||||
Object isPaintPlainBackgroundObj = c.getClientProperty(isPaintPlainBackgroundKey);
|
||||
//如果ClientProperty中没有设置,则尝试取UIManager中的该属性默认值
|
||||
if (isPaintPlainBackgroundObj == null)
|
||||
isPaintPlainBackgroundObj = UIManager.getBoolean(isPaintPlainBackgroundKey);
|
||||
if (isPaintPlainBackgroundObj != null)
|
||||
isPaintPlainBackground = (Boolean) isPaintPlainBackgroundObj;
|
||||
|
||||
//* 如果用户作了自定义颜色设置则使用父类方法来实现绘制,否则BE LNF中没法支持这些设置哦
|
||||
if (isPaintPlainBackground || isUseParentPaint())
|
||||
super.paint(g, c);
|
||||
else {
|
||||
//* 根据工具条所放在父类的位置不同来决定它的背景该使用哪个图片(图片的差别在于方向不同,主要是边缘阴影的方向)
|
||||
NinePatch np = ICON_9.get("north");
|
||||
//int orientation = toolBar.getOrientation();
|
||||
Container parent = toolBar.getParent();
|
||||
if (parent != null) {
|
||||
LayoutManager lm = parent.getLayout();
|
||||
if (lm instanceof BorderLayout) {
|
||||
Object cons = ((BorderLayout) lm).getConstraints(toolBar);
|
||||
if (cons != null)
|
||||
if (cons.equals(BorderLayout.NORTH))
|
||||
np = ICON_9.get("north");
|
||||
else if (cons.equals(BorderLayout.SOUTH))
|
||||
np = ICON_9.get("south");
|
||||
else if (cons.equals(BorderLayout.WEST))
|
||||
np = ICON_9.get("west");
|
||||
else if (cons.equals(BorderLayout.EAST))
|
||||
np = ICON_9.get("east");
|
||||
}
|
||||
}
|
||||
np.draw((Graphics2D) g, 0, 0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rollover border.
|
||||
*
|
||||
* @param b the b
|
||||
* @return the rollover border {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Border getRolloverBorder(AbstractButton b) {
|
||||
return new BEButtonUI.BEEmptyBorder(new Insets(3, 3, 3, 3));
|
||||
}
|
||||
|
||||
//* 由jb2011修改,只加了一行代码哦
|
||||
/**
|
||||
* 重写父类方法实现自已的容器监听器. 自定义的目的就是为了把加入到其中的组件设置为透明,因为BE LNF的工具栏是有背景,否则
|
||||
* 因有子组件的背景存在而使得整体很难看.
|
||||
*
|
||||
* @return the container listener
|
||||
*/
|
||||
@Override
|
||||
protected ContainerListener createToolBarContListener() {
|
||||
return new ToolBarContListenerJb2011();
|
||||
}
|
||||
//* 由jb2011修改自父类的Handler里的ContainerListener监听代码
|
||||
|
||||
/**
|
||||
* The Class ToolBarContListenerJb2011.
|
||||
*/
|
||||
protected class ToolBarContListenerJb2011 implements ContainerListener {
|
||||
//
|
||||
// ContainerListener
|
||||
//
|
||||
|
||||
@Override
|
||||
public void componentAdded(ContainerEvent evt) {
|
||||
Component c = evt.getChild();
|
||||
|
||||
if (toolBarFocusListener != null)
|
||||
c.addFocusListener(toolBarFocusListener);
|
||||
|
||||
if (isRolloverBorders())
|
||||
setBorderToRollover(c);
|
||||
else
|
||||
setBorderToNonRollover(c);
|
||||
|
||||
//## Bug FIX:Issue 51(https://code.google.com/p/beautyeye/issues/detail?id=51)
|
||||
//* 由Jack Jiang201210-12日注释掉:它样做将导致各种放入的组
|
||||
//* 件(如文本框)等都将透明,从而不绘制该 组件的背景,那就错误了哦
|
||||
//* 其实以下代码原本是为了解决放入到JToggleButton的白色背景问题,现在它
|
||||
//* 已经在BEToolgleButtonUI里解决了,此处就不需要了,也不应该要!
|
||||
// //* 只有它一行是由jb2011加的
|
||||
// if(c instanceof JComponent)
|
||||
// ((JComponent)c).setOpaque(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved(ContainerEvent evt) {
|
||||
Component c = evt.getChild();
|
||||
|
||||
if (toolBarFocusListener != null)
|
||||
c.removeFocusListener(toolBarFocusListener);
|
||||
|
||||
// Revert the button border
|
||||
setBorderToNormal(c);
|
||||
}
|
||||
}
|
||||
|
||||
//* 本类由Jack Jiang实现,参考了com.sun.java.swing.plaf.windows.WindowsBorders.getToolBarBorder
|
||||
/**
|
||||
* 工具条边框,左边(或右、或上方)有拖动触点的绘制,方便 告之用户它是可以拖动的 A border for the ToolBar. If the
|
||||
* ToolBar is floatable then the handle grip is drawn
|
||||
* <p>
|
||||
* @since 1.4
|
||||
*/
|
||||
public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants {
|
||||
|
||||
/**
|
||||
* The shadow.
|
||||
*/
|
||||
protected Color shadow;
|
||||
/**
|
||||
* The highlight.
|
||||
*/
|
||||
protected Color highlight;
|
||||
protected Insets insets;
|
||||
|
||||
/**
|
||||
* Instantiates a new tool bar border.
|
||||
*
|
||||
* @param shadow the shadow
|
||||
* @param highlight the highlight
|
||||
*/
|
||||
public ToolBarBorder(Color shadow, Color highlight, Insets insets) {
|
||||
this.highlight = highlight;
|
||||
this.shadow = shadow;
|
||||
this.insets = insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
g.translate(x, y);
|
||||
|
||||
//需要绘制拖动触点
|
||||
if (((JToolBar) c).isFloatable()) {
|
||||
boolean vertical = ((JToolBar) c).getOrientation() == VERTICAL;
|
||||
|
||||
//虚线样式
|
||||
Stroke oldStroke = ((Graphics2D) g).getStroke();
|
||||
Stroke sroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_BEVEL, 0, new float[] { 1, 1 }, 0);//实线,空白
|
||||
((Graphics2D) g).setStroke(sroke);
|
||||
// int gap_top = 5,gap_bottom = 4; //!!10,-1
|
||||
if (!vertical) {
|
||||
int gap_top = 8, gap_bottom = 8;
|
||||
if (c.getComponentOrientation().isLeftToRight()) {
|
||||
int drawX = 3;
|
||||
drawTouchH(g, drawX, gap_top - 1, drawX, height - gap_bottom - 1);
|
||||
} else {
|
||||
int drawX = 3 - 1;
|
||||
drawTouchH(g, width - drawX, gap_top - 1, width - drawX, height - gap_bottom - 1);
|
||||
}
|
||||
} else // Vertical
|
||||
{
|
||||
int gap_left = 8, gap_right = 8;
|
||||
int drawY = 3;
|
||||
drawTouchV(g, gap_left - 1, drawY, width - gap_right - 1, drawY);
|
||||
}
|
||||
|
||||
((Graphics2D) g).setStroke(oldStroke);
|
||||
}
|
||||
|
||||
g.translate(-x, -y);
|
||||
}
|
||||
|
||||
//水平工具条的触点绘制方法
|
||||
private void drawTouchH(Graphics g, int x1, int y1, int x2, int y2) {
|
||||
//第1条竖虚线(深色)
|
||||
g.setColor(shadow);
|
||||
g.drawLine(x1, y1, x1, y2 - 1);
|
||||
//第2条竖虚线(与第1条形成立体效果的浅色,Y坐标相对第1条下偏一个像素)
|
||||
g.setColor(highlight);
|
||||
g.drawLine(x1 + 1, y1 + 1, x1 + 1, y2);
|
||||
|
||||
//第3条竖虚线
|
||||
g.setColor(shadow);
|
||||
g.drawLine(x1 + 2, y1, x1 + 2, y2 - 1);
|
||||
//第4条竖虚线(与第3条形成立体效果的浅色,Y坐标相对第3条下偏一个像素)
|
||||
g.setColor(highlight);
|
||||
g.drawLine(x1 + 3, y1 + 1, x1 + 3, y2);
|
||||
}
|
||||
//垂直工具条的触点绘制方法
|
||||
|
||||
private void drawTouchV(Graphics g, int x1, int y1, int x2, int y2) {
|
||||
//第1条横虚线(深色)
|
||||
g.setColor(shadow);
|
||||
g.drawLine(x1, y1, x2 - 1, y2);
|
||||
//第2条横虚线(与第1条形成立体效果的浅色,X坐标相对第1条右偏一个像素)
|
||||
g.setColor(highlight);
|
||||
g.drawLine(x1 + 1, y1 + 1, x2, y2 + 1);
|
||||
|
||||
//第3条横虚线
|
||||
g.setColor(shadow);
|
||||
g.drawLine(x1, y1 + 2, x2 - 1, y2 + 2);
|
||||
//第4条横虚线(与第3条形成立体效果的浅色,X坐标相对第3条右偏一个像素)
|
||||
g.setColor(highlight);
|
||||
g.drawLine(x1 + 1, y1 + 3, x2, y2 + 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
//** 根据toolbar所放面板的方位不同而设置不一样的border(参照的目标是水平toolbar时的insets)!
|
||||
//tollbar上下设置的空白多一点看起来大气一些(它也将决定toolbar的整体高度和宽度哦)
|
||||
final Insets DEFAILT_IS = insets;//8,0,9,0);//6, 0, 11, 0);
|
||||
Insets is = DEFAILT_IS;
|
||||
if (c instanceof JToolBar) {
|
||||
Container parent = c.getParent();
|
||||
if (parent != null) {
|
||||
LayoutManager lm = parent.getLayout();
|
||||
if (lm instanceof BorderLayout) {
|
||||
Object cons = ((BorderLayout) lm).getConstraints((JToolBar) c);
|
||||
if (cons != null)
|
||||
if (cons.equals(BorderLayout.NORTH))
|
||||
is = DEFAILT_IS;
|
||||
else if (cons.equals(BorderLayout.SOUTH))
|
||||
is = new Insets(DEFAILT_IS.bottom, 0, DEFAILT_IS.top, 0);
|
||||
else if (cons.equals(BorderLayout.WEST))
|
||||
is = new Insets(0, DEFAILT_IS.top, 0, DEFAILT_IS.bottom);
|
||||
else if (cons.equals(BorderLayout.EAST))
|
||||
is = new Insets(0, DEFAILT_IS.bottom, 0, DEFAILT_IS.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getBorderInsets(c, is);//5, 0, 10, 0));//默认是 1,1,1,1
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
// insets.top = insets.left = insets.bottom = insets.right = 1;
|
||||
if (((JToolBar) c).isFloatable()) {
|
||||
// int gripInset = (XPStyle.getXP() != null) ? 12 : 9;//原windows外观中默认的
|
||||
int gripInset = 9;
|
||||
if (((JToolBar) c).getOrientation() == HORIZONTAL)
|
||||
if (c.getComponentOrientation().isLeftToRight())
|
||||
insets.left = gripInset;
|
||||
else
|
||||
insets.right = gripInset;
|
||||
else
|
||||
insets.top = gripInset;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user