I use some classes to get my main frame preferences (locaion and size). Here the following code I use. It works well on Linux and Windows. Buton macOs I have a strange error.
Indeed, if I resize the windows to fit the screen (manually, not with the maximize button) and I close the app. The app will reopen with a tiny size at the left bottom of my screen. It only occurs when I quit with the frame having a full size.
It is like if frame.setSize(dim) does not work when dim has dimension greater than the screen.
However, I also tried to write this code in WindoHandler with no sucess:
Preferences prefs = Preferences.userRoot().node(WindowHandler.class.getSimpleName() + "-" + frameUniqueId);
Dimension savedDim = getFrameSize(prefs, defaultW, defaultH);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// The following test is needed on macOS.
if ((savedDim.getWidth() >= screenSize.getWidth()) || (savedDim.getHeight() >= screenSize.getHeight())) {
frame.setSize(screenSize);
frame.setLocation(new Point(0, 0));
} else {
frame.setSize(savedDim);
frame.setLocation(getFrameLocation(prefs, defaultX, defaultY));
}
EDIT:
I also tried:
frame.setPreferredSize(getFrameSize(prefs, defaultW, defaultH));
frame.setLocation(getFrameLocation(prefs, defaultX, defaultY));
frame.pack();
with no sucess too....
My classes:
package org.spview.preferences;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.prefs.Preferences;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.spview.Main;
//import com.apple.eawt.FullScreenUtilities;
public class WindowHandler {
public static void registerFrame(JFrame frame, String frameUniqueId, int defaultX, int defaultY, int defaultW,
int defaultH) {
Preferences prefs = Preferences.userRoot().node(WindowHandler.class.getSimpleName() + "-" + frameUniqueId);
frame.setSize(getFrameSize(prefs, defaultW, defaultH));
frame.setLocation(getFrameLocation(prefs, defaultX, defaultY));
CoalescedEventUpdater updater = new CoalescedEventUpdater(400, () -> updatePref(frame, prefs));
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
updater.update();
}
#Override
public void componentMoved(ComponentEvent e) {
updater.update();
}
});
}
private static void updatePref(JFrame frame, Preferences prefs) {
Point location = frame.getLocation();
prefs.putInt("x", location.x);
prefs.putInt("y", location.y);
Dimension size = frame.getSize();
prefs.putInt("w", size.width);
prefs.putInt("h", size.height);
}
private static Dimension getFrameSize(Preferences pref, int defaultW, int defaultH) {
int w = pref.getInt("w", defaultW);
int h = pref.getInt("h", defaultH);
return new Dimension(w, h);
}
private static Point getFrameLocation(Preferences pref, int defaultX, int defaultY) {
int x = pref.getInt("x", defaultX);
int y = pref.getInt("y", defaultY);
return new Point(x, y);
}
}
package org.spview.preferences;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class CoalescedEventUpdater {
private Timer timer;
public CoalescedEventUpdater(int delay, Runnable callback) {
timer = new Timer(delay, e -> {
timer.stop();
callback.run();
});
}
public void update() {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(() -> {
timer.restart();
});
} else {
timer.restart();
}
}
}
package org.spview;
import org.spview.preferences.WindowHandler;
import org.spview.gui.JobPlay;
import java.util.Locale;
/**
* This is the entry point to SPVIEW application.
*/
public class Main {
public final static String PACKAGE_NAME = "SPVIEW";
public final static String VERSION = "1.99";
/**
* Start SPVIEW application.
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Locale.setDefault(Locale.ENGLISH); // messages in english
WindowHandler.setLookAndFeel();
JobPlay jp = new JobPlay(); // instantiate the JobPlay main window
WindowHandler.registerFrame(jp, Main.class.getName(), 0, 0, 1024, 768);
jp.setVisible(true); // show it
}
});
}
}
Related
I have a Java program that uses a bunch of JFrame objects. To make it easier to clean up desktop, I want to implement that the current focused window can be closed with Ctrl + w.
I tried to use a keybinding (in the superclass of any view) whose Action's actionPerformed method contains this:
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
This works quite well – as long as I use only one window. It only works, when the last-opened frame is focused, and it only closes that one.
My question is:
Why does the keybinding behaves like this? (I guess it's by design.)
How to create a keybinding per frame without adding any single component to a KeyListener.
Why does the keybinding behaves like this? (I guess it's by design.)
I'd guess you're doing something wrong, but without any kind of example code, it's impossible to know what
How to create a keybinding per frame without adding any single component to a KeyListener
There's a number of ways you might use to achieve this...
Global based solution...
One approach is to take a "global" approach, using a system which doesn't rely on you extending from a root solution, but which can be applied to just about any existing or future project.
AWTEventListener
One solution might be to attach a AWTEventListener to the Toolkit. This is quite low level and provides you access into the ALL the key events which the system is processing
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.KeyEvent;
import javax.swing.FocusManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
private int count = 0;
private int xPos = 10;
private int yPos = 10;
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
installKeyboardMonitor();
for (int index = 0; index < 10; index++) {
makeWindow();
}
}
});
}
public static void installKeyboardMonitor() {
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
KeyEvent ke = (KeyEvent) event;
if (ke.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("Pressed");
if (ke.getKeyCode() == KeyEvent.VK_W) {
System.out.println("W Key");
if (ke.isControlDown()) {
System.out.println("Control down");
Window window = FocusManager.getCurrentManager().getActiveWindow();
if (window != null) {
window.dispose();
}
}
}
}
}
}, AWTEvent.KEY_EVENT_MASK);
}
public void makeWindow() {
count++;
JFrame frame = new JFrame("Test " + count);
frame.setContentPane(new JPanel(new BorderLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
frame.add(new JLabel("Window " + count));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocation(xPos, yPos);
frame.setVisible(true);
xPos += 100;
yPos += 100;
}
}
KeyEventDispatcher
This is slightly less low level then the AWTEventListener but it focus only on KeyEvents which makes it a little easier to manage, but is essentially the same idea
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.event.KeyEvent;
import javax.swing.FocusManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
private int count = 0;
private int xPos = 10;
private int yPos = 10;
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
installKeyboardMonitor();
for (int index = 0; index < 10; index++) {
makeWindow();
}
}
});
}
public static void installKeyboardMonitor() {
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent ke) {
if (ke.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("Pressed");
if (ke.getKeyCode() == KeyEvent.VK_W) {
System.out.println("W Key");
if (ke.isControlDown()) {
System.out.println("Control down");
Window window = FocusManager.getCurrentManager().getActiveWindow();
if (window != null) {
window.dispose();
return true;
}
}
}
}
return false;
}
});
}
public void makeWindow() {
count++;
JFrame frame = new JFrame("Test " + count);
frame.setContentPane(new JPanel(new BorderLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
frame.add(new JLabel("Window " + count));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocation(xPos, yPos);
frame.setVisible(true);
xPos += 100;
yPos += 100;
}
}
Configurable solution
Another solution is to provide a "configuration" based solution. This is similar to the concept of having a base component, but frees you from been locked into a single extension point.
This approach is a little more troublesome, as you actually need to remember to apply to every window and dialog your application might create.
It simply uses the Key Bindings API to register a binding against the windows JRootPane, but you could use just about any component which you know isn't going to be removed from the window.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
private int count = 0;
private int xPos = 10;
private int yPos = 10;
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
for (int index = 0; index < 10; index++) {
makeWindow();
}
}
});
}
public static void installKeyBindings(JComponent component) {
InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = component.getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_DOWN_MASK), "Window.close");
actionMap.put("Window.close", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.windowForComponent(component);
if (window != null) {
window.dispose();
}
}
});
}
public void makeWindow() {
count++;
JFrame frame = new JFrame("Test " + count);
installKeyBindings(frame.getRootPane());
frame.setContentPane(new JPanel(new BorderLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
frame.add(new JLabel("Window " + count));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocation(xPos, yPos);
frame.setVisible(true);
xPos += 100;
yPos += 100;
}
}
After thoughts
This is just three possible solutions. It wouldn't take to much effort to provide a more configurable based solution around each one (so you could supply the key stroke), but I'll leave that up to you
I want to create auto-disposing message dialog. Everything works beside that there is still an ok button to click.
I want to get read the button.
Please check out this code -> works perfectly:
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class CloseOptionPane {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final JLabel label = new JLabel();
int timerDelay = 1000;
new Timer(timerDelay, new ActionListener() {
int timeLeft = 3;
#Override
public void actionPerformed(ActionEvent e) {
if(timeLeft > 0) {
label.setText("Human player. It is your move!");
timeLeft--;
} else {
((Timer) e.getSource()).stop();
Window win = SwingUtilities.getWindowAncestor(label);
win.setVisible(false);
}
}
}) {
{
setInitialDelay(0);
}
}.start();
JOptionPane.showMessageDialog(null, label);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have a JMenu of 16 JMenuItems, of which I want 3 items to be displayed upfront and the rest 13 items to fade in with a 500 ms delay. Is there a way to do this animation in Java?
This is not as easy as it sounds.
Basically I originally thought "I'll attach a popup listener to the popup menu that the menu items are added to"...but apparently this doesn't work so well. The menu popup is built dynamically on demand. Makes sense, but it's still a pain.
So instead, I've found that if I wait for addNotify I can simply start the animation engine.
The animation engine is a simple concept. It has a javax.swing.Timer that ticks at a regular interval. Coupled with a start time and a duration, we can calculate the progress of the animation and generate the alpha value as required.
The only thing left is then to notify all the interested parties that the animation has changed and voila...
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class FadeMenu {
private AnimationEngine engine;
public static void main(String[] args) {
new FadeMenu();
}
public FadeMenu() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
engine = new AnimationEngine();
JMenuBar mb = new JMenuBar();
JMenu flip = new JMenu("Flip");
flip.add("Static 1");
flip.add("Static 2");
flip.add("Static 3");
flip.add(new FadeMenuItem("Fade 1"));
flip.add(new FadeMenuItem("Fade 2"));
flip.add(new FadeMenuItem("Fade 3"));
flip.add(new FadeMenuItem("Fade 4"));
mb.add(flip);
JFrame frame = new JFrame("Testing");
frame.setJMenuBar(mb);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class FadeMenuItem extends JMenuItem {
public FadeMenuItem(String text) {
super(text);
engine.addTimingListener(new TimingListener() {
#Override
public void timingEvent() {
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(engine.getAlpha()));
super.paintComponent(g2d);
g2d.dispose();
}
#Override
public void removeNotify() {
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.stop();
}
super.removeNotify();
}
#Override
public void addNotify() {
super.addNotify();
Container parent = getParent();
if (parent instanceof JPopupMenu) {
JPopupMenu menu = (JPopupMenu) parent;
engine.restart();
}
}
}
public interface TimingListener {
public void timingEvent();
}
public class AnimationEngine {
private Timer fade;
private float alpha;
private long startTime;
private long duration = 1000;
private List<TimingListener> listeners;
public AnimationEngine() {
listeners = new ArrayList<>(5);
fade = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed >= duration) {
((Timer) e.getSource()).stop();
alpha = 1f;
} else {
alpha = (float) elapsed / (float) duration;
}
fireTimingEvent();
}
});
fade.setRepeats(true);
fade.setCoalesce(true);
fade.setInitialDelay(500);
}
public void addTimingListener(TimingListener listener) {
listeners.add(listener);
}
public void removeTimingListener(TimingListener listener) {
listeners.add(listener);
}
protected void fireTimingEvent() {
for (TimingListener listener : listeners) {
listener.timingEvent();
}
}
public void restart() {
fade.stop();
alpha = 0;
fireTimingEvent();
startTime = System.currentTimeMillis();
fade.start();
}
public float getAlpha() {
return alpha;
}
public void stop() {
fade.stop();
}
}
}
While this works on Windows, I'd be concerned that it might not work on other platforms, as the means by which the menus are generated are controlled (in part) by the UI delegate. This could become very messy, very quickly
start a timer to fire an event to fade in
I've got an application that uses custom buttons all over the place for text and icons. Works great for windows and linux, but now OSX users are complaining. Text doesn't display on the mac, just '...'. The code seems simple enough, but I'm clueless when it comes to macs. How can I fix this?
Test case:
package example.swingx;
import example.utils.ResourceLoader;
import com.xduke.xlayouts.XTableLayout;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import java.awt.*;
import java.awt.event.ActionEvent;
public class SmallButton extends JButton {
private static ComponentUI ui = new SmallButtonUI();
public SmallButton() {
super();
/* final RepaintManager repaintManager = RepaintManager.currentManager(this);
repaintManager.setDoubleBufferingEnabled(false);
setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);*/
}
public SmallButton(AbstractAction action) {
super(action);
}
public SmallButton(String text) {
super(text);
}
public SmallButton(Icon icon) {
super(icon);
}
public void updateUI() {
setUI(ui);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel buttonPanel = new JPanel(new XTableLayout());
SmallButton firstSmallButton = new SmallButton("One");
SmallButton secondSmallButton = new SmallButton("Two");
SmallButton thirdSmallButton = new SmallButton();
ImageIcon cameraIcon = (ImageIcon) ResourceLoader.getIcon("camera");
SmallButton fourth = new SmallButton();
fourth.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("Fourth button pressed!");
}
});
fourth.setIcon(cameraIcon);
buttonPanel.add(firstSmallButton, "+");
buttonPanel.add(secondSmallButton, "+");
buttonPanel.add(thirdSmallButton, "+");
buttonPanel.add(fourth, "+");
final Container container = frame.getContentPane();
container.add(buttonPanel);
frame.pack();
frame.setVisible(true);
}
}
UI:
package example.swingx;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
public class SmallButtonUI extends BasicButtonUI {
private static final Color FOCUS_COLOR = new Color(0, 0, 0);
private static final Color BACKGROUND_COLOR = new Color(173, 193, 226);
private static final Color SELECT_COLOR = new Color(102, 132, 186);
private static final Color DISABLE_TEXT_COLOR = new Color(44, 44, 61);
private static final Insets DEFAULT_SMALLBUTTON_MARGIN = new Insets(2, 4, 2, 4);
private final static SmallButtonUI smallButtonUI = new SmallButtonUI();
public static ComponentUI createUI(JComponent component) {
return smallButtonUI;
}
protected Color getSelectColor() {
return SELECT_COLOR;
}
protected Color getDisabledTextColor() {
return DISABLE_TEXT_COLOR;
}
protected Color getFocusColor() {
return FOCUS_COLOR;
}
public void paint(Graphics g, JComponent c) {
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g, c);
}
protected void paintButtonPressed(Graphics graphics, AbstractButton button) {
if (button.isContentAreaFilled()) {
Dimension size = button.getSize();
graphics.setColor(getSelectColor());
graphics.fillRect(0, 0, size.width, size.height);
}
}
public Dimension getMinimumSize(JComponent component) {
final AbstractButton button = ((AbstractButton) component);
// Handle icon buttons:
Icon buttonIcon = button.getIcon();
if (buttonIcon != null) {
return new Dimension(
buttonIcon.getIconWidth(),
buttonIcon.getIconHeight()
);
}
// Handle text buttons:
final Font fontButton = button.getFont();
final FontMetrics fontMetrics = button.getFontMetrics(fontButton);
final String buttonText = button.getText();
if (buttonText != null) {
final int buttonTextWidth = fontMetrics.stringWidth(buttonText);
return new Dimension(buttonTextWidth + 15,
fontMetrics.getHeight() + 5);
}
return null;
}
protected void installDefaults(AbstractButton button) {
super.installDefaults(button);
button.setMargin(DEFAULT_SMALLBUTTON_MARGIN);
button.setBackground(getBackgroundColor());
}
private Color getBackgroundColor() {
return BACKGROUND_COLOR;
}
public Dimension getPreferredSize(JComponent component) {
return getMinimumSize(component);
}
public Dimension getMaximumSize(JComponent component) {
return super.getMinimumSize(component);
}
public SmallButtonUI() {
super();
}
}
EDIT: After debugging, it seems getMinimumSize() is the same on both platforms. Also, when I stop on anywhere Graphics is used, it seems that the mac has a transY value of 47, while linux has 0. This 47 seems to feed into the clipping regions as well. Where could that be getting set?\
Your calculation of preferred size is incorrect.
BasicButtonUI uses SwingUtilities.layoutCompoundLabel, examined here. In a label, the ellipsis is added if the string is too long, but a button is typically sized to fit its entire text.
Absent a better understanding of your context, I would use a sizeVariant, shown below. I've also shown a simple BasicButtonUI example using a smaller, derived Font. The UI menu can be used in conjunction with Quaqua for testing.
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicButtonUI;
/**
* #see https://stackoverflow.com/a/14599176/230513
* #see https://stackoverflow.com/a/11949899/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(new Color(0xfff0f0f0));
f.setLayout(new GridLayout(0, 1));
f.add(createToolBar(f));
f.add(variantPanel("mini"));
f.add(variantPanel("small"));
f.add(variantPanel("regular"));
f.add(variantPanel("large"));
JPanel customPanel = new JPanel();
customPanel.add(createCustom("One"));
customPanel.add(createCustom("Two"));
customPanel.add(createCustom("Three"));
f.add(customPanel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static JPanel variantPanel(String size) {
JPanel variantPanel = new JPanel();
variantPanel.add(createVariant("One", size));
variantPanel.add(createVariant("Two", size));
variantPanel.add(createVariant("Three", size));
return variantPanel;
}
private static JButton createVariant(String name, String size) {
JButton b = new JButton(name);
b.putClientProperty("JComponent.sizeVariant", size);
return b;
}
private static JButton createCustom(String name) {
JButton b = new JButton(name) {
#Override
public void updateUI() {
super.updateUI();
setUI(new CustomButtonUI());
}
};
return b;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
private static class CustomButtonUI extends BasicButtonUI {
private static final Color BACKGROUND_COLOR = new Color(173, 193, 226);
private static final Color SELECT_COLOR = new Color(102, 132, 186);
#Override
protected void paintText(Graphics g, AbstractButton b, Rectangle r, String t) {
super.paintText(g, b, r, t);
g.setColor(SELECT_COLOR);
g.drawRect(r.x, r.y, r.width, r.height);
}
#Override
protected void paintFocus(Graphics g, AbstractButton b,
Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
super.paintFocus(g, b, viewRect, textRect, iconRect);
g.setColor(Color.blue.darker());
g.drawRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);
}
#Override
protected void paintButtonPressed(Graphics g, AbstractButton b) {
if (b.isContentAreaFilled()) {
g.setColor(SELECT_COLOR);
g.fillRect(0, 0, b.getWidth(), b.getHeight());
}
}
#Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
b.setFont(b.getFont().deriveFont(11f));
b.setBackground(BACKGROUND_COLOR);
}
public CustomButtonUI() {
super();
}
}
private static JToolBar createToolBar(final Component parent) {
final UIManager.LookAndFeelInfo[] available =
UIManager.getInstalledLookAndFeels();
List<String> names = new ArrayList<String>();
for (UIManager.LookAndFeelInfo info : available) {
names.add(info.getName());
}
final JComboBox combo = new JComboBox(names.toArray());
String current = UIManager.getLookAndFeel().getName();
combo.setSelectedItem(current);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
int index = combo.getSelectedIndex();
try {
UIManager.setLookAndFeel(
available[index].getClassName());
SwingUtilities.updateComponentTreeUI(parent);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
});
JToolBar bar = new JToolBar("L&F");
bar.setLayout(new FlowLayout(FlowLayout.LEFT));
bar.add(combo);
return bar;
}
}
I'm trying to show and hide a panel during run time, so I call the methods from another class:
Con.Action(1);
to this method:
public void Action(int whichPanel) {
if (whichPanel == 1) {
if (frame.Data.isVisible()) {
frame.Data.setVisible(false);
// frame.splitPaneSec.remove(frame.Data);
} else {
System.out.println(".....");
//frame.Data.setVisible(false);
frame.Data.setVisible(true);
//frame.getContentPane().validate();
//frame.revalidate();
//frame.repaint();
//frame.pack();
}
}
So far i'm able to hide a panel but I can't show it again once I hidden it.
I've tried many ways some of them are commented out.
Any help is appreciated, cheers
I think I would rather remove and add it back.
parent.remove(dataPanel);
parent.validate();
parent.repaint();
parent.add(dataPanel);
parent.validate();
parent.repaint();
I highly recommed you to use enums for Tasks like this:
public void Action(int whichPanel) {
if (whichPanel == 1) {}
//Better;
public void Action(enumType myPanel){
if(myPanel == enumType.LoginScreen){}
with `
public enum enumType
{
LoginScreen,EditScreen //...
}`
You can hide and show Enums if you perfom the setVisible method directly on the Panel you want to show:
public void showLoginScreen()
{
loginPanel.setVisible(true);
registerMenu.setVisible(false);
}
The issue was because after setting the component back to visible
it was required to GUIClass.splitPane.setDividerLocation(157);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
public class HidePanel extends JFrame {
private static final int PANEL_HEIGHT = 50;
private static final int INITIAL_PANEL_WIDTH = 50;
private static final int TIMER_INTERVAL = 1;
private static final int PIXEL_DELTA = 2;
private Dimension panelDimension = new Dimension(INITIAL_PANEL_WIDTH, PANEL_HEIGHT);
private int vertOffset = -PANEL_HEIGHT;
private Timer showTimer = new HidePanel.ShowPanelTimer();
private Timer hideTimer = new HidePanel.HidePanelTimer();
static JLayeredPane lpane = new JLayeredPane();
JPanel panel = new JPanel();
public HidePanel() {
setBackground(Color.BLACK);
setLayout(null);
panel.setBounds(1200, 50, 100, 600);
panel.setBorder(new TitledBorder(new EtchedBorder(), "Hide"));
panel.add(new JButton("Click Me"));
lpane.add(panel);//, //new Integer(0), 0);
add(panel);
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
final int height = e.getY() - 100 ;
if (height < 50 && !showTimer.isRunning() && !panel.isVisible()) {
showTimer.start();
} else if (height > PANEL_HEIGHT + 5 && !hideTimer.isRunning() && panel.isVisible()) {
hideTimer.start();
}
}
});
}
public static void main(String args[]) {
HidePanel h = new HidePanel();
h.setSize(1350, 700);
h.setVisible(true);
h.add(lpane, BorderLayout.CENTER);
}
private void positionPanel(final int offset) {
int panelWidth = getWidth();
System.out.println(" offset = " + offset);
panelDimension.setSize(panelWidth, PANEL_HEIGHT);
//panel.setBounds(insets.left, offset + insets.top, size.width, size.height);
}
private class ShowPanelTimer extends Timer implements ActionListener {
ShowPanelTimer() {
super(TIMER_INTERVAL, null);
addActionListener(this);
}
public void start() {
vertOffset = -PANEL_HEIGHT;
panel.setVisible(true);
super.start();
}
public void actionPerformed(ActionEvent e) {
if (vertOffset <= 0) {
positionPanel(vertOffset);
} else {
showTimer.stop();
}
vertOffset += PIXEL_DELTA;
}
}
private class HidePanelTimer extends Timer implements ActionListener {
HidePanelTimer() {
super(TIMER_INTERVAL, null);
addActionListener(this);
}
public void stop() {
panel.setVisible(false);
super.stop();
}
public void actionPerformed(ActionEvent e) {
if (vertOffset >= (-PANEL_HEIGHT)) {
vertOffset -= PIXEL_DELTA;
positionPanel(vertOffset);
} else {
hideTimer.stop();
}
}
}
}