I have a JPopupMenu and I want to change it's inner size dynamically depending on it's inner components' size. In my SSCCE I described the problem.
SSCCE:
public class PopupTest2 {
public static void main(String[] a) {
final JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createLineBorder(Color.RED));
final JPopupMenu menu = new JPopupMenu();
// critical step
JPanel itemPanel = new JPanel();
itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.Y_AXIS));
final JMenuItem[] items = new JMenuItem[10];
for (int i = 0; i < 10; i++) {
JMenuItem item = new JMenuItem("Item #"+String.valueOf(i));
itemPanel.add(item);
items[i] = item;
}
menu.add(itemPanel);
JToggleButton button = new JToggleButton("Press me");
button.addActionListener(new ActionListener() {
boolean pressed = false;
#Override
public void actionPerformed(ActionEvent e) {
pressed = !pressed;
if (pressed) {
for (JMenuItem item : items) {
item.setText(item.getText()+" changed");
}
} else {
for (JMenuItem item : items) {
item.setText(item.getText().substring(0, item.getText().length() - 8));
}
}
}
});
panel.add(button, BorderLayout.NORTH);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
menu.show(panel, (int) (e.getX() - menu.getPreferredSize().getWidth()), e.getY());
}
}
});
frame.setContentPane(panel);
frame.setUndecorated(true);
frame.setBackground(new Color(50, 50, 50, 200));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
}
}
Steps 2 reproduce:
Right-click to show popup menu.
Click the Press me button (on the top of window).
Right-click to show popup menu again (bug #1 - popup is still small-size)
Right-click to show popup menu again (popup menu size is OK)
Click the Press me button again.
Right-click to show popup menu. (bug #2 - popup is still large-size)
How can I force JPopupMenu to change its size before showing? And why does it work if I add items directly to popupMenu?
Here is one way to do this:
public static void main(String[] a) {
final JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createLineBorder(Color.RED));
final JPopupMenu menu = new JPopupMenu();
// critical step
final JPanel itemPanel = new JPanel();
itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.Y_AXIS));
final JMenuItem[] items = new JMenuItem[10];
for (int i = 0; i < 10; i++) {
JMenuItem item = new JMenuItem("Item #"+String.valueOf(i));
itemPanel.add(item);
items[i] = item;
}
menu.add(itemPanel);
JToggleButton button = new JToggleButton("Press me");
button.addActionListener(new ActionListener() {
boolean pressed = false;
#Override
public void actionPerformed(ActionEvent e) {
pressed = !pressed;
if (pressed) {
for (JMenuItem item : items) {
item.setText(item.getText()+" changed");
item.setMaximumSize(new Dimension(70, 50));
item.setPreferredSize(new Dimension(70, 50));
item.setMinimumSize(new Dimension(70, 50));
itemPanel.invalidate();
}
} else {
for (JMenuItem item : items) {
item.setText(item.getText().substring(0, item.getText().length() - 8));
item.setMaximumSize(new Dimension(130, 50));
item.setPreferredSize(new Dimension(130, 50));
item.setMinimumSize(new Dimension(130, 50));
itemPanel.invalidate();
}
}
}
});
panel.add(button, BorderLayout.NORTH);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
menu.show(panel, (int) (e.getX() - menu.getPreferredSize().getWidth()), e.getY());
}
}
});
frame.setContentPane(panel);
frame.setUndecorated(true);
frame.setBackground(new Color(50, 50, 50, 200));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
}
Thanks all, but I've found the solution after continuous debugging. The problem was in layout used in JPanel (between Popup and items). It called the getPreferredSize() of JPanel which called directly menuItem.getPrefferedSize(), which called BasicMenuItemUI.getPrefferedSize(). The last method uses the MainMenuLayoutHelper class to get the preferred size. This class stores the data about size in Properties static object.
The default JPopupMenu layout - DefaultMenuLayout - clears this static data each time its preferredLayoutSize() method called, with call MenuItemLayoutHelper.clearUsedClientProperties(popupMenu). We will do the same - call this method with our JPanel parameter with further revalidate() call:
public class PopupTest2 {
public static void main(String[] a) {
final JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new BorderLayout());
final JPopupMenu menu = new JPopupMenu();
final JPanel itemPanel = new JPanel();
itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.Y_AXIS));
final JMenuItem[] items = new JMenuItem[1];
for (int i = 0; i < 1; i++) {
JMenuItem item = new JMenuItem("Item #"+String.valueOf(i));
itemPanel.add(item);
items[i] = item;
}
menu.updateUI();
menu.add(itemPanel);
JToggleButton button = new JToggleButton("Press me");
button.addActionListener(new ActionListener() {
boolean pressed = false;
#Override
public void actionPerformed(ActionEvent e) {
pressed = !pressed;
if (pressed) {
for (JMenuItem item : items) {
item.setText(item.getText()+" changed");
}
} else {
for (JMenuItem item : items) {
item.setText(item.getText().substring(0, item.getText().length() - 8));
}
}
}
});
panel.add(button, BorderLayout.NORTH);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
MenuItemLayoutHelper.clearUsedClientProperties(itemPanel);
itemPanel.revalidate();
menu.show(panel, (int) (e.getX() - menu.getPreferredSize().getWidth()), e.getY());
}
}
});
frame.setContentPane(panel);
frame.setUndecorated(true);
frame.setBackground(new Color(50, 50, 50, 200));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
}
}
PS: Dear reader, it is not the best way to write your code. I do that because I really need that (I have such requirements). If you can build your JPopupMenu without JPanel inside, do not use code in this answer, please.
You have to add
menu.updateUI();
after add menu items.
final JMenuItem[] items = new JMenuItem[10];
for (int i = 0; i < 10; i++) {
JMenuItem item = new JMenuItem("Item #"+String.valueOf(i));
itemPanel.add(item);
item.setUI(new MyUI());
items[i] = item;
}
menu.updateUI(); <<<<<<--------
menu.add(itemPanel);
Related
I'm trying to use JCombobox inside the JPopupMenu, but without success, popup becomes visible when user clicks the label,
label = new JLabel();
label.addMouseListener(this);
this is the label code, with mouse listener, on mousePressed and mouseClicked events it does display and hide popup menu, inside the menu I have JPanel which contains ButtonGroup, click on buttons displays different JPanel's in the center of the panel, short exmaple of panel and popup menu code looks like this
popupPanel = new JPanel();
popupPanel.setLayout(new BorderLayout());
menu = new JPopupMenu();
menu.add(BorderLayout.CENTER, popupPanel);
menu.pack();
menu.addPopupMenuListener(this);
popup panel contains button groups as i mentioned above, when one of the buttons is clicked it displays
color_combo_panel = new JPanel();
color_combo_panel.setLayout(new GridBagLayout());
color_combo = new JComboBox<>();
color_combo.addItem(Color.RED.toString());
color_combo.addItem(Color.BLUE.toString());
color_combo.addItem(Color.CYAN.toString());
color_combo.setRenderer(new ColorRenderer());
panel containing JCombobox, problem starts from here, when I click on combo box to select the color, JPopupMenu gets closed, on the ather hand JCombobox selection does nothing, my question is, how can I force popup menu to stay visible, with mouse and popup listeners i have forced it to stay visible, but as a result I get IllegalComponentStateException, component must be shown on the screen, I found problem similar to mine, but it do not provide relevant solution, plus this behavior is submitted as a BUG here.
will much appreciate any useful advice
EDIT minimal reproducible example asked by #camickr
public class PopupTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(500, 500));
frame.setLayout(new GridBagLayout());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new ColorCombo());
frame.setVisible(true);
}
static class ColorCombo extends JComboBox {
private static final long serialVersionUID = 2L;
public ColorCombo() {
setPreferredSize(new Dimension(200, 30));
}
#Override
public void updateUI() {
ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
if (cui instanceof MetalComboBoxUI) {
cui = new MetalBrushComboBoxUI();
} else {
cui = new BasicBrushComboboxUI();
}
setUI(cui);
}
class MetalBrushComboBoxUI extends MetalComboBoxUI {
#Override
protected ComboPopup createPopup() {
return new ColorPopup(comboBox);
}
}
class BasicBrushComboboxUI extends BasicComboBoxUI {
#Override
protected ComboPopup createPopup() {
return new ColorPopup(comboBox);
}
}
class ColorPopup extends MouseAdapter implements ComboPopup, ActionListener {
private JList list = new JList();
private JComboBox comboBox;
private JPopupMenu popupMenu;
private JPanel container, first_color_panel;
public ColorPopup(JComboBox comboBox) {
this.comboBox = comboBox;
container = new JPanel();
container.setLayout(new BorderLayout());
JToggleButton first_button = new JToggleButton();
first_button.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2, false));
first_button.setPreferredSize(new Dimension(20, 20));
first_button.setBackground(Color.WHITE);
first_button.addActionListener(this);
first_button.setActionCommand("color1");
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(first_button);
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
northPanel.add(first_button);
first_color_panel = new JPanel();
first_color_panel.setLayout(new GridBagLayout());
JComboBox<String> color_combo = new JComboBox<>();
color_combo.setPreferredSize(new Dimension(120, 30));
for (String color : getColors().keySet())
color_combo.addItem(color);
color_combo.setRenderer(new ColorRenderer());
color_combo.addActionListener(this);
color_combo.setActionCommand("color1_ground");
first_color_panel.add(color_combo);
container.add(northPanel, BorderLayout.NORTH);
popupMenu = new JPopupMenu();
popupMenu.add(BorderLayout.CENTER, container);
}
#Override
public void actionPerformed(ActionEvent e) {
boolean isSet = container.getComponents().length == 2;
if ("color1".equals(e.getActionCommand())) {
if (isSet)
container.remove(1);
container.add(first_color_panel, BorderLayout.CENTER);
}
container.revalidate();
popupMenu.repaint();
}
#Override
public void show() {
this.container.setPreferredSize(new Dimension(this.comboBox.getWidth(), 100));
popupMenu.add(BorderLayout.CENTER, container);
popupMenu.pack();
popupMenu.show(this.comboBox, 0, this.comboBox.getHeight());
}
#Override
public void hide() {
popupMenu.setVisible(false);
}
#Override
public boolean isVisible() {
return popupMenu.isVisible();
}
#Override
public JList getList() {
return list;
}
#Override
public MouseListener getMouseListener() {
return this;
}
#Override
public MouseMotionListener getMouseMotionListener() {
return this;
}
#Override
public KeyListener getKeyListener() {
return null;
}
#Override
public void uninstallingUI() {
}
#Override
public void mouseClicked(MouseEvent e) {
comboBox.requestFocus();
toggle();
}
private void toggle() {
if (isVisible()) {
hide();
} else {
show();
}
}
private Map<String, Color> getColors() {
Map<String, Color> colors = new HashMap<>();
colors.put("Red", Color.RED);
colors.put("blue", Color.BLUE);
colors.put("green", Color.GREEN);
colors.put("Yellow", Color.YELLOW);
return colors;
}
class ColorRenderer extends JPanel implements ListCellRenderer<String> {
#Override
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout(3, 3));
panel.setBorder(BorderFactory.createCompoundBorder(getBorder(),
BorderFactory.createEmptyBorder(0, 0, 3, 0)));
JLabel label = new JLabel();
label.setOpaque(true);
label.setPreferredSize(new Dimension(20, label.getHeight()));
label.setBackground(getColors().get(value));
JLabel text = new JLabel();
text.setText(value);
panel.add(label, BorderLayout.WEST);
panel.add(text, BorderLayout.CENTER);
return panel;
}
}
}
}}
I am trying to make a program in which, On Selecting JToggleButton shows a Sliding Drawer animated Panel and on deselecting it Hides it.
I want something like this on Clicking Toggle Button,
| Toggle button|---->|Panel|
Slides the Panel like a drawer
and on Deselecting Toggle Button
|Toggle Button|<-----|Hides panel|
I am able to create a new panel on Selecting a JToggle Button but i am confused with creating the animation.
myToggleButton.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
if(ev.getStateChange()==ItemEvent.SELECTED){
myPanel.add(slidingPanel,BorderLayout.CENTER);
myPanel.revalidate();
myPanel.repaint();
} else if(ev.getStateChange()==ItemEvent.DESELECTED){
myPanel.remove(slidingPanel);
myPanel.revalidate();
myPanel.repaint();
}
}
});
How can i achieve sliding Drawer animation for a panel on a ToggleButton click and then hiding the panel .
I was able to figure out how to achieve it.I am writing the code for help.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SlidePanelDemo extends JPanel {
private JPanel pnlMain;
private JFrame frame;
private JPanel contentPane;
private static int drawWidth = 200;
private static int drawHeight = 100;
private Timer timer;
private int graphWidth = 5;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SlidePanelDemo().createAndShowGUI();
}
});
}
public void createAndShowGUI() {
JToggleButton button = new JToggleButton("Tools");
button.setSize(30, 30);
button.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
if (ev.getStateChange() == ItemEvent.SELECTED) {
System.out.println("button is selected");
timer = new Timer(40, (ActionEvent e1) -> {
graphWidth = graphWidth + 5;
System.out.println("graphWidth is" + graphWidth);
pnlMain.setSize(graphWidth, drawHeight);
pnlMain.setVisible(true);
if (graphWidth >= 0 && graphWidth == drawWidth) {
timer.stop();
}
});
timer.setRepeats(true);
timer.start();
} else if (ev.getStateChange() == ItemEvent.DESELECTED) {
System.out.println("button is not selected");
timer = new Timer(40, (ActionEvent e1) -> {
graphWidth = graphWidth - 5;
System.out.println("graphWidth is" + graphWidth);
if (graphWidth > 0 && graphWidth <= drawWidth) {
pnlMain.setSize(graphWidth, drawHeight);
pnlMain.setVisible(true);
}
if (graphWidth == 5) {
timer.stop();
}
});
timer.setRepeats(true);
timer.start();
}
}
});
pnlMain = createMainPanel();
JButton label = new JButton("Click");
JButton label2 = new JButton("Click me");
pnlMain.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
pnlMain.add(label);
pnlMain.add(label2);
contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
contentPane.setOpaque(true);
contentPane.add(button);
contentPane.add(pnlMain);
pnlMain.setVisible(true);
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame("Slide Out Panel Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(contentPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setSize(500, 300);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(graphWidth, drawHeight);
}
};
panel.setBorder(BorderFactory.createTitledBorder("Main"));
return panel;
}
}
I've created a modal dialog inside a JFrame using the glass pane. My display method is quite simple: it creates a JPanel as glass pane with some alpha background and adds the JLabel and an ok and close button. Then the glass pane is set and displayed via frame.getGlassPane().setVisible(true);.
Everything works fine: if I call the method the pane is displayed and I can click ok or cancel and the glass pane hides. But the method returns directly after showing the glass pane. But I want it to behave like the JOptionPane methods: they block until the dialog is closed.
But everytime I'm trying to insert any kind of busy waiting at the end of my show method the GUI is frozen if I click the open button. I've also tried to get the mechanism from JDialog#show() but that's a bit to complicated for me.
So how to block the show method while the glass pane is visible?
Here is a simple example:
public class GlassPaneSSCE extends JPanel {
private JFrame parentFrame;
public GlassPaneSSCE(JFrame parent) {
parentFrame = parent;
addKeyListener(new KeyAdapter() {});
addMouseListener(new MouseAdapter() {});
setBackground(new Color(0, 0, 0, 100));
initGui();
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
private void initGui() {
setLayout(new FlowLayout(FlowLayout.CENTER));
setOpaque(false);
final JPanel content = new JPanel(new BorderLayout(4, 4));
content.setOpaque(true);
content.setBorder(new EmptyBorder(8, 8, 8, 8));
JLabel top = new JLabel("Title of this little modal dialog");
content.add(top, BorderLayout.NORTH);
JPanel inner = new JPanel(new BorderLayout());
content.add(inner, BorderLayout.CENTER);
inner.add(new JScrollPane(new JList(new String[] {
"Item 1 ",
"Item 2", "Item 3"
})));
Box ctrlButtons = Box.createHorizontalBox();
ctrlButtons.setBorder(new EmptyBorder(0, 4, 4, 4));
ctrlButtons.add(Box.createHorizontalGlue());
ctrlButtons.add(new JButton(new AbstractAction("OK") {
#Override
public void actionPerformed(ActionEvent e) {
parentFrame.getGlassPane().setVisible(false);
parentFrame.setGlassPane(new JPanel());
}
}));
content.add(ctrlButtons, BorderLayout.SOUTH);
add(content);
}
public void display() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
parentFrame.setGlassPane(GlassPaneSSCE.this);
parentFrame.getGlassPane().setVisible(true);
// Set the focus on the glass pane
requestFocus();
setFocusCycleRoot(true);
}
});
// The next line should be executed only if
// the ok button is clicked and not before
System.out.println("End of display()");
}
public static void main(String[] args) {
final JFrame f = new JFrame();
f.setLayout(new FlowLayout(FlowLayout.CENTER));
JTextArea tp = new JTextArea(10, 10);
for (int i = 0; i < 20; i++) {
JButton b = new JButton("Open");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GlassPaneSSCE gp = new GlassPaneSSCE(f);
gp.display();
}
});
f.add(b);
tp.append("Item " + (i+1) + "\n");
}
f.add(new JScrollPane(tp));
f.setSize(600, 600);
f.setVisible(true);
}
}
I have 2 classes; Students and RegisterStudents, and hence 2 different main_panel(Class 1) and panel_1 (Class 2). What I am trying to do is, when a button on the Students Interface is pressed, the whole panel_1 should appear within main_panel. I have set both to same size already. is that possible?
The code i got so far is:
JButton btnNewButton = new JButton("Register Student");
btnNewButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
Students main_panel = new Students();
RegisterStudent panel_1 = new RegisterStudent();
main_panel.add(panel_1);
}
});
btnNewButton.setBounds(0, 162, 167, 37);
panel.add(btnNewButton);
This isnt doing anything though? its compiling, but panel_1 is not actually appearing inside the main_panel. Has anyone got any suggestions?
JButton btnNewButton = new JButton("Register Student");
btnNewButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
Students main_panel = new Students();
RegisterStudent panel_1 = new RegisterStudent();
main_panel.add(panel_1);
panel.add(main_panel); // ADD THIS LINE
}
});
btnNewButton.setBounds(0, 162, 167, 37);
panel.add(btnNewButton);
You were initializing the new main_panel, and new panel_1, and adding panel_1 to main_panel but then you weren't doing anything with the new main_panel.
Also, I highly suggest naming your variables otherwise - these names are very non-intuitive.
For such things I would suggest you to use CardLayout
When you add something to the container, you must call revalidate() and repaint() methods to realize the changes made to it at RunTime. Like in your case you adding main_panel.add(panel_1);now after this you must perform
main_panel.revalidate();
main_panel.repaint();
frame.getRootPane().revalidate(); // for Upto JDK 1.6.
frame.revalidate(); // for JDK 1.7+
frame.repaint();
so that changes can be seen. A small code snippet to help you understand what I mean.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MultiplePanels extends JFrame
{
private JPanel registrationPanel, loginPanel, searchPanel;
private JButton registerButton, loginButton, searchButton;
private ActionListener action;
public MultiplePanels()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
registrationPanel = new JPanel();
registrationPanel.setBackground(Color.WHITE);
loginPanel = new JPanel();
loginPanel.setBackground(Color.YELLOW);
searchPanel = new JPanel();
searchPanel.setBackground(Color.BLUE);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(0, 1));
buttonPanel.setBackground(Color.DARK_GRAY);
registerButton = new JButton("REGISTER");
loginButton = new JButton("LOGIN");
searchButton = new JButton("SEARCH");
buttonPanel.add(registerButton);
buttonPanel.add(loginButton);
buttonPanel.add(searchButton);
action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
if (button == registerButton)
{
if (!(loginPanel.isShowing()) && !(searchPanel.isShowing()))
{
add(registrationPanel, BorderLayout.CENTER);
}
else
{
if (loginPanel.isShowing())
{
remove(loginPanel);
add(registrationPanel, BorderLayout.CENTER);
}
else if (searchPanel.isShowing())
{
remove(searchPanel);
add(registrationPanel, BorderLayout.CENTER);
}
}
}
else if (button == loginButton)
{
if (!(registrationPanel.isShowing()) && !(searchPanel.isShowing()))
{
add(loginPanel, BorderLayout.CENTER);
}
else
{
if (registrationPanel.isShowing())
{
remove(registrationPanel);
add(loginPanel, BorderLayout.CENTER);
}
else if (searchPanel.isShowing())
{
remove(searchPanel);
add(loginPanel, BorderLayout.CENTER);
}
}
}
else if (button == searchButton)
{
if (!(loginPanel.isShowing()) && !(registrationPanel.isShowing()))
{
add(searchPanel, BorderLayout.CENTER);
}
else
{
if (loginPanel.isShowing())
{
remove(loginPanel);
add(searchPanel, BorderLayout.CENTER);
}
else if (registrationPanel.isShowing())
{
remove(registrationPanel);
add(searchPanel, BorderLayout.CENTER);
}
}
}
// This is what we are doing here to realize the changes
// made to the GUI.
revalidate();
repaint();
}
};
registerButton.addActionListener(action);
loginButton.addActionListener(action);
searchButton.addActionListener(action);
add(buttonPanel, BorderLayout.LINE_START);
setSize(300, 300);
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new MultiplePanels();
}
});
}
}
I want to add/hide/remove jlayeredpanes dynamically on runtime and also should hide the contents on each pane when another pane is selected. I have tried the following code and i am not sure how to do this. The following code hides the content of each pane when alternate pane is selected but it does not hide its content constantly. When we mousemove over the hidden content area they are made visible again. Plz help me out in this!!
public class floorsetup {
public static void createfloor(String name)
{
String name1=name+"_pane";
JButton b = new JButton(name);
final JLayeredPane jp = new JLayeredPane();
jp.setName(name1);
floor_plan.dynamicPane_floors.put(name1, jp);
//jp.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jp.setAutoscrolls(true);
jp.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
jp.setMinimumSize(new java.awt.Dimension(1000, 700));
jp.setOpaque(true);
jp.setBounds(floor_plan.ground.getBounds());
floor_plan.jLayeredPane2.add(jp);
jp.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
//floor_plan.jLayeredPane2.setVisible(false);
int x = 0,y = 0;
//ComponentOrientation componentOrientation = jLayeredPane2.getComponentOrientation();
// Rectangle bounds = jLayeredPane2..getBounds();
// x=bounds.x;
//y=bounds.y;
//System.out.println(bounds);
x=evt.getX();
y=evt.getY();
System.out.println(x);
System.out.println(y);
// String name=floor_plan.table_name.getText();
String name="some name";
if(floor_plan.delete!=1)
tablesetup.addButton(name,x,y, (JLayeredPane) evt.getSource());
System.out.println((evt.getSource()));
}
});
b.setActionCommand(name);
b.setAlignmentX(Component.CENTER_ALIGNMENT);
b.setPreferredSize(new Dimension(125, 25));
b.setBackground(Color.green);
floor_plan.floors.add(b);
floor_plan.floors.add(Box.createRigidArea(new Dimension(10, 15)));
// b.setSize(125, 25);
floor_plan.dynamicButtons_floors.put(name, b);
MouseListenerClass M1 = new MouseListenerClass();
MouseClass M2 = new MouseClass();
b.addMouseMotionListener(M1);
b.addMouseListener(M2);
b.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
if(floor_plan.delete==1)
{
removeButton(evt.getActionCommand());
}
else if(floor_plan.edit==1)
{
String edit_name = JOptionPane.showInputDialog("Name of the button:");
JButton source = (JButton) evt.getSource();
source.setActionCommand(edit_name);
source.setText(edit_name);
floor_plan.dynamicButtons_floors.put(edit_name, source);
}
else
{
String switcher=evt.getActionCommand();
switcher+="_pane";
switch_pane(switcher,evt);
}
}
});
floor_plan.floors.validate();
floor_plan.floors.repaint();
}
public static void removeButton(String name) {
JButton b = floor_plan.dynamicButtons_floors.remove(name);
floor_plan.jLayeredPane2.remove(b);
floor_plan.jLayeredPane2.invalidate();
floor_plan.jLayeredPane2.repaint();
}
public static void switch_pane(String name,ActionEvent evt)
{
JLayeredPane jp = floor_plan.dynamicPane_floors.get(name);
System.out.println(floor_plan.jLayeredPane2);
System.out.println(jp);
floor_plan.ground.setVisible(false);
floor_plan.ground.setEnabled(false);
jp.setVisible(true);
jp.moveToFront(floor_plan.ground);
}
}
This is the bit of code using getText(). but i am getting error!!
if(floor_plan.delete==1)
{
JButton source = (JButton) evt.getSource();
int index=floor_plan.floors.getComponentCount();
int val=0;
Component[] components = floor_plan.floors.getComponents();
for(int i=0; i<index;i++)
{
System.out.println(source.getName());
if(components[i].getText().equals(source.getName()))
{
val=i;
}
}
removeButton(evt.getActionCommand(),val);
}
It sounds like you might want to look at the JTabbedPane. This will allow you to have multiple tabs with different content in each tab. When a user selects a tab, only the content on that tab is shown.
Links:
JTabbedPane Javadocs
JTabbedPane Tutorial
To dynamically add a tab through a button, you could use code similar to the following:
JButton newTabButton = new JButton("Add Tab");
newTabButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JPanel newTab = new JPanel();
newTab.setLayout(null);
// Dynamic panel is a JTabbedPane
dynamicPanel.addTab(JOptionPane.showInputDialog("Name of tab"), newTab);
}
});