I'm attempting to overlap JPanel instances. Put a panel directly on another, in the exact same position and exact size. Every time I do this it moves the other panel to the other side or underneath, the previous panel is inside another much larger one and has buttons in it.
How would I do this? Keep in mind it's using the Window Builder tool.
You might also want to look at OverlayLayout, seen here. It's not included in the conventional gallery, but it may be of interest.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
/** #see http://stackoverflow.com/a/13437388/230513 */
public class OverlaySample {
public static void main(String args[]) {
JFrame frame = new JFrame("Overlay Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new OverlayLayout(panel));
panel.add(create(1, "One", Color.gray.brighter()));
panel.add(create(2, "Two", Color.gray));
panel.add(create(3, "Three", Color.gray.darker()));
frame.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private static JLabel create(final int index, String name, Color color) {
JLabel label = new JLabel(name) {
private static final int N = 64;
#Override
public boolean isOpaque() {
return true;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(index * N, index * N);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(index * N, index * N);
}
};
label.setHorizontalAlignment(JLabel.RIGHT);
label.setVerticalAlignment(JLabel.BOTTOM);
label.setBackground(color);
label.setAlignmentX(0.0f);
label.setAlignmentY(0.0f);
return label;
}
}
I'm attempting to overlap JPanels
Use a JLayeredPane (image below from the linked tutorial).
Put a JPanel directly on another,
..or a CardLayout as shown here..
..depending on which of those two you mean, since I understand them as quite different effects.
Use a JDesktopPane (or its superclass JLayeredPane) as its content, adding to the pane.
See How to Use Internal Frames for examples.
Here you can see a nice way of letting components overlay, and pop up when the cursor rests on it:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ShiftedStackPanel extends JPanel implements MouseListener,
ActionListener {
private static final long serialVersionUID = 1988454751139668485L;
private int layer;
private JDesktopPane desktopPane;
private Timer timer;
private Component currentComponent;
private int layerOfCurrent;
private int shiftDivision;
public ShiftedStackPanel() {
this(4);
}
public ShiftedStackPanel(int shift) {
shiftDivision = shift;
setLayout(new BorderLayout(0, 0));
desktopPane = new JDesktopPane();
desktopPane.setBackground(SystemColor.window);
super.add(desktopPane);
timer = new Timer(1000, this);
timer.setRepeats(false);
}
public Component add(Component c) {
Dimension dim = c.getPreferredSize();
c.setBounds(
(desktopPane.getComponentCount() * (dim.width / shiftDivision)),
0, dim.width, dim.height);
desktopPane.add(c, new Integer(++layer));
c.addMouseListener(this);
return c;
}
public void remove(Component c) {
throw new IllegalArgumentException(
"Removal of component, not yet supported.");
// FIXME: allow removal, and shift all latter comps, to left
}
public void removeAll() {
desktopPane.removeAll();
}
public static void main(String[] args) {
JFrame f = new JFrame("JFrame Wrapper");
ShiftedStackPanel p;
f.setContentPane(p = new ShiftedStackPanel(4));
p.add(new JTextField("ABCDEFGHI"));
p.add(new JTextField("DEFGHIJKL"));
p.add(new JTextField("GHIJKLMNO"));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setMinimumSize(new Dimension(400, 200));
f.setLocationRelativeTo(null);
}
#Override
public void mouseClicked(MouseEvent evt) {
if (currentComponent != null) {
Component c = (Component) evt.getSource();
currentComponent = c;
layerOfCurrent = desktopPane.getLayer(c);
desktopPane.remove(c);
desktopPane.add(c, new Integer(100));
}
}
#Override
public void mouseEntered(MouseEvent evt) {
timer.start();
Component c = (Component) evt.getSource();
currentComponent = c;
layerOfCurrent = desktopPane.getLayer(c);
}
#Override
public void mouseExited(MouseEvent evt) {
if ((currentComponent != null) && currentComponent == evt.getSource()) {
desktopPane.remove(currentComponent);
desktopPane.add(currentComponent, new Integer(layerOfCurrent));
currentComponent = null;
timer.stop();
}
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent arg0) {
desktopPane.remove(currentComponent);
desktopPane.add(currentComponent, new Integer(100));
}
}
Still has some problems, when using components that require focus, but should work well with JLabel, and JPanel.
Related
It doesn't appear that my thread ever starts. Either that or the run method isn't actually doing anything, for which reason I could not explain.
I have a listener on my button StartRace and it should start the thread which will increment the length of each rectangle until one of them is long enough to be declared winner (by surpassing the width of the window, 250px).
I get all of the components initially painted to the screen, but they're never repainted. Is there something wrong with the way I call the method? Do I have classes nested within others that shouldn't be?
//--------------------------------------------------------------
// Start a race between blue and red, track the winner
// Use threads to manage each rectangle's movement
// Allow for user interaction, like stopping and starting
//--------------------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class ConcurrencyRace extends JFrame
{
private ConcurrencyPanel panel = new ConcurrencyPanel();
private JButton startRace = new JButton("Start The Race!");
private JButton stopRace = new JButton("Stop The Race!");
private JLabel winnerText = new JLabel("Winner: ");
private int blueDraw = 5, redDraw = 5;
private Random rn = new Random();
//-----------------------------------------------------------------
// Creates and displays the main program frame.
//-----------------------------------------------------------------
public ConcurrencyRace() {
super("Concurrency");
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
cp.add(panel, BorderLayout.CENTER);
JPanel p = new JPanel();
p.add(startRace);
p.add(stopRace);
cp.add(p, BorderLayout.NORTH);
cp.add(winnerText, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main (String[] args)
{
ConcurrencyRace tRun = new ConcurrencyRace();
tRun.setVisible(true);
}
private class ConcurrencyPanel extends JPanel
{
public class runnerThread extends Thread {
#Override
public void run() {
while (blueDraw < 250 && redDraw < 250) {
panel.validate();
panel.repaint();
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
}
}
}
public ConcurrencyPanel ()
{
setPreferredSize(new Dimension(600,250));
}
private class ButtonListener implements ActionListener {
runnerThread rectDraw = new runnerThread();
//--------------------------------------------------------------
// Starts the thread to draw each rectangle ("racer")
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
if (event.getSource() == startRace) {
rectDraw.start();
}
}
}
#Override
public void paintComponent (Graphics page) {
super.paintComponent(page);
page.setColor(Color.blue);
page.fillRect(0,80,blueDraw,20);
page.setColor(Color.red);
page.fillRect(0,120,redDraw,20);
blueDraw += rn.nextInt(10) + 1;
redDraw += rn.nextInt(10) + 1;
page.dispose();
}
}
}
Primarily
You never add a ActionListener to either of your buttons, so nothing is responding when they are activated
Additionally
The state management is all over the place. blueDraw and redDraw should be instance fields of ConcurrencyPanel.
Don't update the state of the UI (or variables which the UI relies on) from within any paint method. Paint methods should paint the state, not change it. Updating the blueDraw and redDraw should be done in a specific method, which can be called when a update is required.
All of that leads me to believe you'd be better of using a Swing Timer
Conceptually...
You could do something like this...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ConcurrencyRace {
//-----------------------------------------------------------------
// Creates and displays the main program frame.
//-----------------------------------------------------------------
public ConcurrencyRace() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Timer timer = new Timer(200, null);
JFrame frame = new JFrame();
frame.add(new ButtonPane(timer), BorderLayout.NORTH);
frame.add(new RacePane(timer));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new ConcurrencyRace();
}
public class ButtonPane extends JPanel {
private JButton startRace = new JButton("Start The Race!");
private JButton stopRace = new JButton("Stop The Race!");
public ButtonPane(Timer timer) {
startRace.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
stopRace.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
setLayout(new GridBagLayout());
add(startRace);
add(stopRace);
}
}
private class RacePane extends JPanel {
private int blueDraw = 5, redDraw = 5;
private Random rn = new Random();
public RacePane(Timer timer) {
timer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (updateState()) {
((Timer)e.getSource()).stop();
}
}
});
}
protected boolean updateState() {
blueDraw += rn.nextInt(10) + 1;
redDraw += rn.nextInt(10) + 1;
repaint();
return blueDraw >= getWidth() || redDraw >= getWidth();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 250);
}
#Override
public void paintComponent(Graphics page) {
System.out.println(">>");
super.paintComponent(page);
page.setColor(Color.blue);
page.fillRect(0, 80, blueDraw, 20);
page.setColor(Color.red);
page.fillRect(0, 120, redDraw, 20);
}
}
}
This maintains the Timer as the central concept, which is shared between the buttons and race panels.
I've not added support for generating notification of a winner, this would be done via a simple observer pattern passed to the RacePane
I'm quite new to java here , and right now i'm working on a program which involves the following actions. Lets say i have a 3 X 3 grid of JLabel. How do i load an ImageIcon and then move it from on label to another. For example, say each label is named as label_1 to label_9, and the imageicon is on label_2 . When i click on label_3,imageicon it should go to label_3
Very quick example which you can adapt to your needs.
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Test extends JFrame {
public Test() {
JPanel container = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
JLabel label = new JLabel("Label" + i);
label.setPreferredSize(new Dimension(100, 100));
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
Icon icon = UIManager.getIcon("OptionPane.informationIcon");
JLabel clickedLabel = (JLabel) e.getSource();
Container parent = clickedLabel.getParent();
clearIcons(parent);
clickedLabel.setIcon(icon);
}
private void clearIcons(Container parent) {
Component[] components = parent.getComponents();
for (Component component : components) {
((JLabel) component).setIcon(null);
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
container.add(label);
}
add(container);
}
public static void main(String[] args) {
Test frame = new Test();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
}
}
Result should be following:
so this is my problem. I have an 8*8 grid of panels, all white. Then, when one of them is clicked, it's supposed to change to a random color. The only problem I have right now is that I don't know how to see if the user clicked their mouse in a specific panel. Here is the code I have so far (I'm going to implement the random element afterwards)
`
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GridOfPanels extends JPanel{
int x, y;
public GridOfPanels(){
JPanel content = new JPanel(new GridLayout(8,8));
for(int i = 0; i < 64; i++){
JPanel panel = new JPanel();
panel.setBackground(Color.white);
content.add(panel);
}
this.add(content);
}
public GridOfPanels(Color backColor){
setBackground(backColor);
addMouseListener(new PanelListener());
x = 200;
y = 200;
}
private class PanelListener extends MouseAdapter{
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
repaint();
}
}
public static void main(String[] args){
JFrame theGUI = new JFrame();
theGUI.setTitle("Grid");
theGUI.setVisible(true);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theGUI.setSize(400,400);
Rectangle z = new Rectangle(x, y, 50, 50);
}
}
`
You have to add a listener to each clickable object. Here is a working example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends JFrame{
public TestFrame(int size){
JPanel content = new JPanel(new GridLayout(size, size));
JPanel[] panel = new JPanel[size * size];
PanelListener listener = new PanelListener();
for(int i = 0; i < panel.length; i++){
panel[i] = new JPanel();
panel[i].setBackground(Color.white);
panel[i].addMouseListener(listener);
content.add(panel[i]);
}
this.add(content);
}
// MouseListener offers the method mouseClicked(MouseEvent e)
private class PanelListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent event) {
/* source is the object that got clicked
*
* If the source is actually a JPanel,
* then will the object be parsed to JPanel
* since we need the setBackground() method
*/
Object source = event.getSource();
if(source instanceof JPanel){
JPanel panelPressed = (JPanel) source;
panelPressed.setBackground(Color.blue);
}
}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
}
public static void main(String[] args){
TestFrame theGUI = new TestFrame(8);
theGUI.setTitle("Grid");
theGUI.setVisible(true);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theGUI.setSize(400,400);
}
}
You have to add MouseListener to one of the panels. Only one panel will react to click event. In the listener cast the source to JPanel and change the color.
I would like to have a JComponent placed and sharing space with other components, differently depending on what configuration I select at runtime. For the first configuration the JComponent is placed in BorderLayout on EAST or WEST side and sharing space with other components in the frame. For the second configuration the JComponent must be placed on top of all the other components, overlapping them and letting them resize.
What I did is create a JPanel with a BorderLayout and place in it all my JComponent in NORTH, CENTER and EAST side. This is the initial configuration. I placed that JPanel in a JLayeredPane DefaultLayer layer and set this JLayeredPane as the content of my JFrame. I would like to use this JLayeredPane to place the EAST side JComponent on upper layer (if 2nd configuration is selected) and put it back to the DefaultLayer (if 1st configuration is selected).
Hope I'm clear and give enough details to have some help. Thanks in advance.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToggleButton;
/**
* #see http://stackoverflow.com/q/13776251/230513
*/
public class NewJavaGUI {
class Desktop {
private JPanel desktop;
private JLayeredPane layeredPane;
private HidingArea hidingArea;
private final JToggleButton toggleShowHide;
public Desktop() {
desktop = new JPanel(new BorderLayout(5, 5));
desktop.setBounds(0, 0, 600, 400);
layeredPane = new JLayeredPane(){
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 400);
}
};
layeredPane.add(desktop);
NorthArea northArea = new NorthArea();
northArea.setLayout(new BoxLayout(northArea, BoxLayout.LINE_AXIS));
toggleShowHide = new JToggleButton("Show");
toggleShowHide.addItemListener(new ShowHideItemListener());
JRadioButton conf1btn = new JRadioButton("In desktop");
conf1btn.setOpaque(false);
JRadioButton conf2btn = new JRadioButton("In layered pane");
conf2btn.setOpaque(false);
ButtonGroup group = new ButtonGroup();
group.add(conf1btn);
group.add(conf2btn);
northArea.add(conf1btn);
northArea.add(conf2btn);
northArea.add(Box.createHorizontalGlue());
northArea.add(toggleShowHide);
conf1btn.addActionListener(new SetComponentInDesktopListener());
conf2btn.addActionListener(new SetComponentInLayeredPaneListener());
desktop.add(northArea, BorderLayout.PAGE_START);
desktop.add(new CenterArea(), BorderLayout.CENTER);
hidingArea = new HidingArea();
desktop.add(hidingArea, BorderLayout.LINE_END);
conf1btn.setSelected(true);
}
/**
* The layered pane is added to the contentPane of a JFrame
*/
JLayeredPane getComponent() {
return layeredPane;
}
private class HidingArea extends JPanel {
public HidingArea() {
setBackground(Color.darkGray);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 400);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 350);
}
}
private class NorthArea extends JPanel {
public NorthArea() {
setBackground(Color.gray);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 50);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(600, 50);
}
}
private class CenterArea extends JPanel {
public CenterArea() {
setBackground(Color.white);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(400, 400);
}
}
/**
* Hide or show the area contained in the JLayeredPane.
*/
private class ShowHideItemListener implements ItemListener {
#Override
public void itemStateChanged(ItemEvent e) {
JToggleButton toggle = (JToggleButton) e.getSource();
if (e.getStateChange() == ItemEvent.SELECTED) {
toggle.setText("Hide");
hidingArea.setBounds(
getBounds().width - hidingArea.getPreferredSize().width,
getBounds().height - hidingArea.getPreferredSize().height,
hidingArea.getPreferredSize().width,
hidingArea.getPreferredSize().height);
} else {
toggle.setText("Show");
hidingArea.setBounds(
getBounds().width,
getBounds().height - hidingArea.getPreferredSize().height,
hidingArea.getPreferredSize().width,
hidingArea.getPreferredSize().height);
}
}
}
/**
* #return the rectangular dimensions of the desktop.
*/
private Rectangle getBounds() {
return desktop.getBounds();
}
/**
* Add Hiding area to desktop.
*/
private class SetComponentInDesktopListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
toggleShowHide.setEnabled(false);
Component[] components = desktop.getComponents();
boolean toAdd = true;
for (Component component : components) {
if (component.equals(hidingArea)) {
toAdd = false;
}
}
if (toAdd) {
desktop.add(hidingArea, BorderLayout.LINE_END);
}
}
}
/**
* Remove Hiding area from desktop and add it to the JLayeredPane.
*/
private class SetComponentInLayeredPaneListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
toggleShowHide.setEnabled(true);
desktop.remove(hidingArea);
getComponent().add(hidingArea, (Integer) (JLayeredPane.DEFAULT_LAYER + 50));
}
}
}
private void display() {
JFrame f = new JFrame("NewJavaGUI");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Desktop d = new Desktop();
f.add(d.getComponent());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new NewJavaGUI().display();
}
});
}
}
I want to make JDialog-based window inactive, so all controls apeared disabled (in grey color). setEnabled(false) just makes impossible to click any control, even close window. But nothing turns gray. Help please.
EDIT: Here is sample code.
import javax.swing.JButton;
import javax.swing.JDialog;
public class Analyzer extends JDialog{
public Analyzer() {
JButton but = new JButton("test");
setLayout(null);
but.setBounds(10,10,100,100);
add(but);
setSize( 200, 200);
setVisible(true);
setEnabled(false);
}
public static void main(String[] args) {
new Analyzer();
}
}
The two ways I know to do this, one where you disable the components of a dialog recursively, and the second where you disable the entire dialog (including ability to drag the dialog):
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class DisableEg extends JPanel {
public static final String DISABLE_DIALOG_COMPONENTS = "Disable Dialog Components";
public static final String ENABLE_DIALOG_COMPONENTS = "Enable Dialog Components";
public static final String DISABLE_DIALOG = "Disable Dialog";
public static final String ENABLE_DIALOG = "Enable Dialog";
private static final int LOC_SHIFT = 150;
private Analyzer analyzer;
public DisableEg(JFrame frame) {
analyzer = new Analyzer(frame);
analyzer.pack();
analyzer.setLocationRelativeTo(frame);
Point location = analyzer.getLocation();
location = new Point(location.x - LOC_SHIFT, location.y - LOC_SHIFT);
analyzer.setLocation(location);
analyzer.setVisible(true);
add(new JButton(new AbstractAction(DISABLE_DIALOG_COMPONENTS) {
#Override
public void actionPerformed(ActionEvent evt) {
AbstractButton btn = (AbstractButton) evt.getSource();
if (btn.getText().equals(DISABLE_DIALOG_COMPONENTS)) {
btn.setText(ENABLE_DIALOG_COMPONENTS);
analyzer.setComponentEnabled(false);
} else {
btn.setText(DISABLE_DIALOG_COMPONENTS);
analyzer.setComponentEnabled(true);
}
}
}));
add(new JButton(new AbstractAction(DISABLE_DIALOG) {
#Override
public void actionPerformed(ActionEvent evt) {
AbstractButton btn = (AbstractButton) evt.getSource();
if (btn.getText().equals(DISABLE_DIALOG)) {
btn.setText(ENABLE_DIALOG);
analyzer.setEnabled(false);
} else {
btn.setText(DISABLE_DIALOG);
analyzer.setEnabled(true);
}
}
}));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Disable Example");
DisableEg mainPanel = new DisableEg(frame);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class Analyzer extends JDialog {
public Analyzer(JFrame frame) {
super(frame, "Analyzer Dialog", false);
JButton but = new JButton("test");
setLayout(new FlowLayout());
add(but);
setPreferredSize(new Dimension(200, 200));
}
public void setComponentEnabled(boolean enabled) {
setComponentEnabled(enabled, getContentPane());
// !! if you have menus to disable, you may need instead
// setComponentEnabled(enabled, this); // !!
}
private void setComponentEnabled(boolean enabled, Component component) {
component.setEnabled(enabled);
if (component instanceof Container) {
Component[] components = ((Container) component).getComponents();
if (components != null && components.length > 0) {
for (Component heldComponent : components) {
setComponentEnabled(enabled, heldComponent);
}
}
}
}
}
The typical way to do this is to use a glassPane, but Java 7 introduced JLayer that should do the trick too.