Мы переходим на Java 11, и в ходе курса нам нужно изменить несколько устаревших кодов.Внешний интерфейс нашего приложения в основном на Swing.Я не очень полезен для этого, поэтому мне нужна помощь / ввод.
В нашем старом коде мы настроили наш LookAndFeel
API, напрямую расширив его до внутреннего API Java WindowsLookAndFeel
.Я попытался решить эту проблему, добавив следующие строки в сценарий сборки:
-add-exports java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED
Но есть несколько проблем, с которыми мы сталкиваемся во время его работы, связанных с пользовательским интерфейсом.
Чтобы полностью решить эту проблемудля будущего выпуска мы планируем использовать MetalLookAndFeel
API.Он работает отлично, но единственная проблема, с которой я сталкиваюсь, связана с обновлением.
Действие не сразу отражается.Допустим, я щелкаю некоторые из вкладок, а затем, чтобы увидеть их, мне нужно свернуть / щелкнуть другую вкладку.
Просто хотел узнать, что я что-то упускаю.
package com.osm.ui.laf.ctc;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalLookAndFeel;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
public class PtcLaf extends MetalLookAndFeel {
private final String ctcPackageName = "com.osm.ui.laf.ctc."; //frozen
private Boolean useCTCWindowDecoration = null;
@Override
public boolean getSupportsWindowDecorations() {
if (useCTCWindowDecoration == null) {
final String val = System.getProperty("use.ctc.window.decoration"); //frozen
if (val != null) {
useCTCWindowDecoration = val.equals("true"); //frozen
} else {
useCTCWindowDecoration = true;
}
}
return useCTCWindowDecoration.booleanValue();
}
@Override
protected void initClassDefaults(UIDefaults table) {
super.initClassDefaults(table);
final Object[] defaults = {
"RootPaneUI", ctcPackageName + "PtcRootPaneUI", //frozen
"MenuItemUI", ctcPackageName + "PtcMenuItemUI", //frozen
"SeparatorUI", ctcPackageName + "PtcSeparatorUI", //frozen
"PopupMenuSeparatorUI", ctcPackageName + "PtcSeparatorUI", //frozen
"RadioButtonMenuItemUI", ctcPackageName + "PtcRadioButtonMenuItemUI", //frozen
"CheckBoxMenuItemUI", ctcPackageName + "PtcCheckBoxMenuItemUI", //frozen
"MenuUI", ctcPackageName + "PtcMenuUI", //frozen
"RibbonApplicationMenuButtonUI", ctcPackageName + "PtcRibbonApplicationMenuButtonUI", //frozen
"RibbonApplicationMenuPopupPanelUI", ctcPackageName + "PtcRibbonApplicationMenuPopupPanelUI", //frozen
"RibbonUI", ctcPackageName + "PtcRibbonUI", //frozen
"RibbonGalleryUI", ctcPackageName + "PtcRibbonGalleryUI", //frozen
"RibbonBandUI", ctcPackageName + "PtcRibbonBandUI", //frozen
"RibbonTaskToggleButtonUI", ctcPackageName + "PtcRibbonTaskToggleButtonUI", //frozen
"CommandButtonUI", ctcPackageName + "PtcCommandButtonUI", //frozen
"EmptyCommandButtonUI", ctcPackageName + "PtcEmptyCommandButtonUI", //frozen
"CommandButtonPanelUI", ctcPackageName + "PtcCommandButtonPanelUI", //frozen
"CommandMenuButtonUI", ctcPackageName + "PtcCommandMenuButtonUI", //frozen
"CommandPopupMenuUI", ctcPackageName + "PtcCommandPopupMenuUI", //frozen
"ScrollablePanelUI", ctcPackageName + "PtcScrollablePanelUI", //frozen
"TabbedPaneUI", ctcPackageName + "PtcTabbedPaneUI", //frozen
"RichTooltipPanelUI", ctcPackageName + "PtcRichTooltipPanelUI", //frozen
"ComboBoxUI", ctcPackageName + "PtcComboBoxUI" //frozen
};
table.putDefaults(defaults);
}
@Override
protected void initComponentDefaults(final UIDefaults table) {
super.initComponentDefaults(table);
initResourceBundle(table);
// Initalise all the defaults.
final Object[] defaults = {
"activeCaption", new ColorUIResource(251, 251, 251), //frozen
"inactiveCaption", new ColorUIResource(200, 200, 200), //frozen
"activeCaptionText", new ColorUIResource(58, 58, 58), //frozen
"inactiveCaptionText", new ColorUIResource(138, 138, 138), //frozen
// Active window colors
"InternalFrame.activeTitleBackground", new ColorUIResource(251, 251, 251), //frozen
"InternalFrame.activeTitleGradient", new ColorUIResource(251, 251, 251), //frozen
"InternalFrame.activeTitleForeground", new ColorUIResource(58, 58, 58), //frozen
// Inactive window colors
"InternalFrame.inactiveTitleBackground", new ColorUIResource(251, 251, 251), //frozen
"InternalFrame.inactiveTitleGradient", new ColorUIResource(251, 251, 251), //frozen
"InternalFrame.inactiveTitleForeground", new ColorUIResource(207, 207, 207), //frozen
// Icons for frames
"InternalFrame.maximizeIcon", LookAndFeel.makeIcon(this.getClass(), "icons/maximize_12x12.png"), //frozen
"InternalFrame.closeIcon", LookAndFeel.makeIcon(this.getClass(), "icons/close_12x12.png"), //frozen
"InternalFrame.minimizeIcon", LookAndFeel.makeIcon(this.getClass(), "icons/restore_12x12.png"), //frozen
"InternalFrame.iconifyIcon", LookAndFeel.makeIcon(this.getClass(), "icons/minimize_12x12.png"), //frozen
// Window borders
"RootPane.frameBorder.radius", 11, //frozen
"RootPane.frameBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.plainDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.informationDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.errorDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.colorChooserDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.fileChooserDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.questionDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
"RootPane.warningDialogBorder", new PtcLazyValue(ctcPackageName + "PtcFrameBorder"), //frozen
// Menu
"MenuItem.selectionBackground", new ColorUIResource(246, 220, 150), //frozen
"MenuItem.selectionBackgroundGradient", new ColorUIResource(251, 238, 203), //frozen
"MenuItem.selectionForeground", new ColorUIResource(0, 0, 0), //frozen
"MenuItem.background", new ColorUIResource(255, 255, 255), //frozen
"MenuItem.foreground", new ColorUIResource(0, 0, 0), //frozen
"MenuItem.disabledForeground", new ColorUIResource(200, 200, 200), //frozen
"MenuItem.lineColor", new ColorUIResource(200, 200, 200), //frozen
"Menu.submenuPopupOffsetX", new Integer(0), //frozen
"Menu.submenuPopupOffsetY", new Integer(-1), //frozen
"PopupMenu.border", BorderFactory.createLineBorder(Color.gray), //frozen
"MenuBar.background", new ColorUIResource(226, 230, 233), //frozen
"MenuItem.borderColor", Color.gray, //new ColorUIResource(226, 230, 233), //frozen
// Toolbar
"ToolBar.background", new ColorUIResource(226, 230, 233), //frozen
"Toolbar.darkColor", new ColorUIResource(226, 230, 233), //frozen
"Toolbar.lightColor", Color.white, //new ColorUIResource(226, 230, 233), //frozen
"WindowsToolBar.underline", Color.gray, //frozen
// Task bars
"Taskbar.head.text.plain", Color.black, //frozen
"Taskbar.head.text.selected", new ColorUIResource(25, 25, 25), //frozen
"Taskbar.head.bar.left", new ColorUIResource(206, 210, 213), //frozen
"Taskbar.head.bar.right", new ColorUIResource(206, 210, 213), //frozen
"Taskbar.item.background", new ColorUIResource(226, 230, 233), //frozen
"SplashScreen.border", new PtcLazyValue(ctcPackageName + "PtcSplashScreenFrameBorder"), //frozen
"SplashScreen.border.radius", 11, //frozen
//Ribbon
"RibbonBand.background", new ColorUIResource(251, 251, 251), //frozen
"RibbonBand.title.background", new ColorUIResource(238, 240, 241), //frozen
"RibbonBand.title.borderline", new ColorUIResource(199, 202, 204), //frozen
"RibbonBand.border", new PtcLazyValue(ctcPackageName + "PtcRibbonBandBorder"), //frozen
"ControlPanel.background", new ColorUIResource(251, 251, 251), //frozen
"RibbonUI.background", new ColorUIResource(251, 251, 251), //frozen
"RibbonApplicationMenuButton.background", new ColorUIResource(238, 240, 241), //frozen
"RibbonApplicationMenuButton.foreground", new ColorUIResource(0, 0, 0), //frozen
"RibbonApplicationMenuButton.border.color", new ColorUIResource(199, 202, 204), //frozen
"Ribbon.border", BorderFactory.createEmptyBorder(), //frozen
"BandHostPanel.background", new ColorUIResource(251, 251, 251), //frozen
// Table selection colors
"Table.selectionForeground", new ColorUIResource(0, 0, 0), //frozen
"Table.selectionBackground", new ColorUIResource(246, 220, 150), //frozen
//Combo box list Colors
"ComboBox.List.selectionForeground", new ColorUIResource(0, 0, 0), //frozen
"ComboBox.List.selectionBackground", new ColorUIResource(246, 220, 150), //frozen
// Tabbed pane colors
"TabbedPane.tabSelectedBackground", new ColorUIResource(246, 220, 150), //frozen
"TabbedPane.tabSelectedBackgroundGradient", new ColorUIResource(251, 238, 203), //frozen
"TabbedPane.borderColor", new ColorUIResource(145, 145, 145), //frozen
"TabbedPane.tabBackground", new ColorUIResource(220, 220, 220), //frozen
"TabbedPane.tabBackgroundGradient", new ColorUIResource(240, 240, 240), //frozen
"QuickSearchField.border.color", new ColorUIResource(199, 202, 204), //frozen
"StatusPanel.background", new ColorUIResource(251, 251, 251), //frozen
};
table.putDefaults(defaults);
}
private void initResourceBundle(UIDefaults table) {
table.addResourceBundle("com.sun.swing.internal.plaf.metal.resources.metal"); //frozen
}
@Override
public String getName() {
return "CTC Look And Feel"; //frozen
}
@Override
public String getID() {
return "CTCLAF"; //frozen
}
@Override
public String getDescription() {
return "CTC Look And Feel"; //frozen
}
@Override
public boolean isNativeLookAndFeel() {
return true;
}
@Override
public boolean isSupportedLookAndFeel() {
return true;
}
}
package com.osm.ui.laf;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import com.osm.datamgmt.ui.WindowManager;
import com.osm.ui.laf.ctc.PtcLaf;
import com.osm.ui.laf.xplookandfeel.XPLookAndFeel;
public class LookAndFeelManager {
private static final Logger log = Logger.getLogger(LookAndFeelManager.class.getName());
private static LookAndFeelManager instance;
final List<LookAndFeelDescriptor> availableLAFs;
private LookAndFeelDescriptor currentLAF;
private LookAndFeelManager() {
// if we wanted to expose all installed LAFs, we'd do something like
/*
UIManager.installLookAndFeel("Windows XP", XPLookAndFeel.class.getName()); //frozen
UIManager.installLookAndFeel("Office 2010", PtcLaf.class.getName()); //frozen
final LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
*/
availableLAFs = new ArrayList<LookAndFeelDescriptor>();
availableLAFs.add(new LookAndFeelDescriptor("Windows XP", XPLookAndFeel.class.getName())); //frozen
availableLAFs.add(new LookAndFeelDescriptor("PTC", PtcLaf.class.getName())); //frozen
currentLAF = findCurrentLAFDescriptor();
}
public static synchronized LookAndFeelManager getInstance() {
if (instance == null) {
instance = new LookAndFeelManager();
}
return instance;
}
public static synchronized void clearInstance() {
instance = null;
}
public List<LookAndFeelDescriptor> getAvailableLookAndFeels() {
return availableLAFs;
}
public LookAndFeelDescriptor getCurrentLookAndFeel() {
return currentLAF;
}
public void setLookAndFeel(LookAndFeelDescriptor lafDescriptor) {
if (lafDescriptor == null) {
log.warning("LAF is null"); //frozen
return;
}
if (lafDescriptor.equals(currentLAF)) {
return;
}
log.info("Setting LAF " + lafDescriptor); //frozen
try {
UIManager.setLookAndFeel(lafDescriptor.getClassName());
currentLAF = lafDescriptor;
final Collection<Window> frames = WindowManager.getInstance().getFrames();
for (Window frame : frames) {
SwingUtilities.updateComponentTreeUI(frame);
}
} catch (Exception e) {
log.log(Level.SEVERE, "Could not set LAF", e); //frozen
}
}
private LookAndFeelDescriptor findCurrentLAFDescriptor() {
final LookAndFeel laf = UIManager.getLookAndFeel();
final String lafClassName = laf.getClass().getName();
for (LookAndFeelDescriptor descriptor : availableLAFs) {
if (lafClassName.equals(descriptor.getClassName())) {
return descriptor;
}
}
log.warning("No LAF descriptor found"); //frozen
return null;
}
// Quite similar to UIManager.LookAndFeelInfo but with a more readable 'toString()'
public static class LookAndFeelDescriptor {
private String name;
private String className;
public LookAndFeelDescriptor(String name, String className) {
this.name = name;
this.className = className;
}
public String getName() {
return name;
}
public String getClassName() {
return className;
}
@Override
public String toString() {
return getName();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof LookAndFeelDescriptor)) {
return false;
}
return className.equals(((LookAndFeelDescriptor) obj).getClassName());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + ((className == null) ? 0 : className.hashCode());
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
return result;
}
}
}