
io.github.homebeaver.swingset.demo.DemoJXFrame Maven / Gradle / Ivy
package io.github.homebeaver.swingset.demo;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JRootPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTheme;
import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.JXStatusBar;
import org.jdesktop.swingx.SwingXUtilities;
import org.jdesktop.swingx.action.AbstractActionExt;
import org.jdesktop.swingx.demos.svg.FlagBR;
import org.jdesktop.swingx.demos.svg.FlagCH;
import org.jdesktop.swingx.demos.svg.FlagCS;
import org.jdesktop.swingx.demos.svg.FlagDE;
import org.jdesktop.swingx.demos.svg.FlagES;
import org.jdesktop.swingx.demos.svg.FlagFR;
import org.jdesktop.swingx.demos.svg.FlagIT;
import org.jdesktop.swingx.demos.svg.FlagNL;
import org.jdesktop.swingx.demos.svg.FlagPL;
import org.jdesktop.swingx.demos.svg.FlagSE;
import org.jdesktop.swingx.demos.svg.FlagUK;
import org.jdesktop.swingx.icon.SizingConstants;
import swingset.TextAndMnemonicUtils;
/**
* multi window Frame used for Demos
*/
@SuppressWarnings("serial")
public class DemoJXFrame extends JXFrame {
private static final Logger LOG = Logger.getLogger(DemoJXFrame.class.getName());
private static final String METAL = "javax.swing.plaf.metal.MetalLookAndFeel";
private static final String STEEL = "javax.swing.plaf.metal.DefaultMetalTheme";
private static final String OCEAN = "javax.swing.plaf.metal.OceanTheme";
// some UI object keys
private static final String UI_KEY_BOLDMETAL = "swing.boldMetal"; // Boolean
private static final String UI_KEY_FRAME_TITLEFONT = "InternalFrame.titleFont"; // Font
public static boolean isMETAL() {
return "Metal".equals(UIManager.getLookAndFeel().getName()); // oder String getID()
}
public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated) {
JFrame.setDefaultLookAndFeelDecorated(defaultLookAndFeelDecorated);
}
private static int windowCounter = 0; // für windowNo, wird pro ctor hochgezählt
int getWindowCounter() {
return windowCounter;
}
private int windowNo;
/**
* get singleton instance of MainJXframe
* @return MainJXframe singleton
*/
public MainJXframe getRootFrame() {
return MainJXframe.getInstance();
}
ButtonGroup lafMenuGroup;
private ButtonGroup lafGroup = null; // wg. mi.setSelected
ButtonGroup getLaFGroup() {
if(lafGroup==null) lafGroup = new ButtonGroup();
return lafGroup;
}
private int window_ID;
JXPanel jPanel = new JXPanel(new BorderLayout());
// Einstellungen vor Frame ctor
static private boolean exitOnClose(int window_ID) {
UIManager.put(UI_KEY_BOLDMETAL, Boolean.FALSE); // turn off bold fonts in Metal
// dieser key gilt nicht für Frame Titel, das macht:
Font font = UIManager.getFont(UI_KEY_FRAME_TITLEFONT);
UIManager.put(UI_KEY_FRAME_TITLEFONT, new Font(font.getName(), Font.PLAIN, font.getSize()));
LOG.info("UI key "+UI_KEY_FRAME_TITLEFONT+" changed to "+UIManager.getFont(UI_KEY_FRAME_TITLEFONT) + " was "+font);
// LOG.info("InternalFrame.closeIcon:"+UIManager.getIcon("InternalFrame.closeIcon"));
if(isMETAL() && window_ID!=-1) { // root Window always OS controlled ID==-1
// decorate Demo Frame Title with STEEL when LaF is METAL
// otherwise no decoration aka OS controlled
setDefaultLookAndFeelDecorated(UIManager.getLookAndFeel().getSupportsWindowDecorations());
}
return window_ID==-1 ? true : false;
}
/*
* window_ID==-1 is used for RootFrame
*/
DemoJXFrame(String title, int window_ID, Object object) {
super(title
, GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()
, exitOnClose(window_ID)
);
windowCounter++;
this.windowNo = windowCounter-1;
this.window_ID = window_ID;
getRootPaneExt().setToolBar(new ToggleButtonToolBar()); // inner Class
// bei RootFrame: setJMenuBar:
if(this instanceof MainJXframe) {
LOG.info("\nthis:"+this);
setJMenuBar(new JMenuBar());
}
}
DemoJXFrame(String title) { // für RootFrame
this(title, -1, null);
}
private static final boolean USE_METALTITLEPANE = true;
protected void frameInit() {
if(USE_METALTITLEPANE || !JFrame.isDefaultLookAndFeelDecorated()) {
super.frameInit();
return;
}
frameInitPatch();
}
// siehe https://github.com/homebeaver/SwingSet/issues/25
private void frameInitPatch() {
// die UI-Farben retten:
Color activeBackground = UIManager.getColor("activeCaption");
Color activeForeground = UIManager.getColor("activeCaptionText");
Color activeShadow = UIManager.getColor("activeCaptionBorder");
// Code aus JFRame:
enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
setLocale( JComponent.getDefaultLocale() );
setRootPane(createRootPane());
setBackground(UIManager.getColor("control"));
setRootPaneCheckingEnabled(true);
if (JFrame.isDefaultLookAndFeelDecorated()) {
boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations) {
UIManager.put("activeCaption", this.getBackground()); // activeBackground wie this
// statt MetalLookAndFeel.getPrimaryControl() in activeBumps ==>
// (UIManager.get("InternalFrame.activeTitleGradient") != null) ? null : MetalLookAndFeel.getPrimaryControl() );
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
Component[] comps = getRootPane().getLayeredPane().getComponentsInLayer(JLayeredPane.FRAME_CONTENT_LAYER);
for(int i=0; i {
SetLanguageAction action = new SetLanguageAction(dl, target);
JMenuItem mi = (JRadioButtonMenuItem) menu.add(new JRadioButtonMenuItem(action));
mi.setText(dl.toString());
mi.setIcon(dl.getIcon());
if(defaultLocale!=null && defaultLocale.toString().startsWith(dl.getLocale().toString())) mi.setSelected(true);
langMenuGroup.add(mi);
});
return menu;
}
JMenu themeMenu;
/**
* Creates a LaF JMenu for metal Themes Menu
* @param target Window
* @return JMenu
*/
protected JMenu createThemeMenu(Window target) {
String[] themeInfo = { OCEAN , STEEL
, "swingset.plaf.AquaTheme"
, "swingset.plaf.CharcoalTheme"
, "swingset.plaf.ContrastTheme"
, "swingset.plaf.EmeraldTheme"
, "swingset.plaf.RubyTheme"
};
String memuLabel = null; // the text for the menu label
try {
// getTextAndMnemonicString throws MissingResourceException
memuLabel = TextAndMnemonicUtils.getTextAndMnemonicString("ThemesMenu.themes.labelAndMnemonic");
} catch (MissingResourceException e) {
memuLabel = "Themes";
}
themeMenu = new JMenu(memuLabel);
ButtonGroup themeMenuGroup = new ButtonGroup(); // wg. mi.setSelected
for (String info : themeInfo) {
JMenuItem mi = (JRadioButtonMenuItem) themeMenu.add(new JRadioButtonMenuItem(info));
themeMenuGroup.add(mi);
SetThemeAction action = new SetThemeAction(info, target);
mi.setAction(action);
}
// setEnabled when LAF is Metal
themeMenu.setEnabled(isMETAL());
if(isMETAL()) {
// set inital selected default:
themeMenu.getItem("Steel".equals(MetalLookAndFeel.getCurrentTheme().getName()) ? 1 : 0).setSelected(true);
}
return themeMenu;
}
/**
* Returns the JXFrame
's status bar. Lazily creates and
* sets an instance if necessary.
* @param frame the target frame
* @return the frame's statusbar
*/
// aus InteractiveTestCase.getStatusBar
static JXStatusBar getStatusBar(JXFrame frame) {
JXStatusBar statusBar = frame.getRootPaneExt().getStatusBar();
if (statusBar == null) {
statusBar = new JXStatusBar();
frame.setStatusBar(statusBar);
}
return statusBar;
}
public JXStatusBar getStatusBar() {
return getStatusBar(this);
}
/**
* Action to toggle plaf and update all toplevel windows of the
* current application. Used to setup the plaf-menu.
*/
private static class SetPlafAction extends AbstractActionExt {
private String plaf;
private Window toplevel;
@SuppressWarnings("unused")
public SetPlafAction(String name, String plaf) {
this(name, plaf, null, null);
}
/**
* Instantiates an action which updates the toplevel window to the given LAF.
*
* @param name the name of the action
* @param plaf the class name of the LAF to set
* @param group identity of the state action
* @param toplevel the window to update, may be null to indicate
* update of all application windows
*/
public SetPlafAction(String name, String plaf, ButtonGroup group, Window toplevel) {
super(name);
super.setGroup(group);
this.plaf = plaf;
this.toplevel = toplevel;
}
/**
* {@inheritDoc}
*/
@Override
public void actionPerformed(ActionEvent e) {
// LOG.info("plaf:"+plaf +", ActionEvent "+e);
try {
UIManager.setLookAndFeel(plaf);
if (toplevel != null) {
SwingUtilities.updateComponentTreeUI(toplevel);
} else {
SwingXUtilities.updateAllComponentTreeUIs();
}
} catch (Exception e1) {
e1.printStackTrace();
LOG.log(Level.FINE, "problem in setting laf: " + plaf, e1);
}
if(toplevel instanceof MainJXframe) {
MainJXframe rf = (MainJXframe)toplevel;
// // themeMenu setEnabled when LAF is Metal
rf.themeMenu.setEnabled(isMETAL());
// JPopupMenu Group (in AbstractActionExt) und JMenu Group synchronisieren:
Enumeration abEnum = rf.lafMenuGroup.getElements();
abEnum.asIterator().forEachRemaining(ab -> {
if(e.getActionCommand().equals(ab.getText())) {
ab.setSelected(true);
}
});
abEnum = rf.getLaFGroup().getElements();
abEnum.asIterator().forEachRemaining(ab -> {
if(e.getActionCommand().equals(ab.getText())) {
ab.setSelected(true);
}
});
}
}
}
private static class SetThemeAction extends AbstractAction {
/*
abstract class MetalTheme
class DefaultMetalTheme extends MetalTheme
class OceanTheme extends DefaultMetalTheme
AquaTheme extends DefaultMetalTheme
...
*/
Class> themeClass = null;
private MetalTheme theme;
private Window toplevel;
public SetThemeAction(Class> themeClass, Window toplevel) {
this(themeClass.getName(), toplevel);
this.themeClass = themeClass;
}
/**
*
* @param name == themeClass name
* @param theme
* @param toplevel
*/
public SetThemeAction(String name, Window toplevel) {
super(name);
this.theme = null;
this.toplevel = toplevel;
}
@Override
public void actionPerformed(ActionEvent event) {
if(!isMETAL()) return;
if (themeClass == null) {
String className = (String) super.getValue(Action.NAME);
try {
themeClass = Class.forName(className); // throws ClassNotFoundException
} catch (Exception e) {
LOG.warning("Error occurred loading class: " + className);
e.printStackTrace();
}
}
try {
theme = (MetalTheme)themeClass.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOG.info("theme:"+theme.getName() +", toplevel "+toplevel);
try {
MetalLookAndFeel.setCurrentTheme(theme);
UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
if (toplevel != null) {
SwingUtilities.updateComponentTreeUI(toplevel);
if(toplevel instanceof MainJXframe) {
MainJXframe rf = (MainJXframe)toplevel;
Window w = rf.currentDemoFrame;
if (w != null) SwingUtilities.updateComponentTreeUI(w);
}
// WindowFrame currentDemoFrame = null;
} else {
SwingXUtilities.updateAllComponentTreeUIs();
}
} catch (Exception e1) {
e1.printStackTrace();
LOG.log(Level.FINE, "problem in setting MetalTheme", e1);
}
}
}
private static class SetLanguageAction extends AbstractAction {
private DisplayLocale dl;
private Window toplevel;
public SetLanguageAction(DisplayLocale dl, Window toplevel) {
super(dl.getLocale().toString());
this.dl = dl;
this.toplevel = toplevel;
}
@Override
public void actionPerformed(ActionEvent e) {
if (toplevel != null) {
LOG.info("Locale selected:"+dl + ", do setComponentTreeLocale for "+toplevel);
SwingXUtilities.setComponentTreeLocale(toplevel, dl.getLocale());
if(toplevel instanceof MainJXframe) {
MainJXframe rf = (MainJXframe)toplevel;
Window w = rf.currentDemoFrame;
if (w != null) SwingXUtilities.setComponentTreeLocale(w, dl.getLocale());
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy