I'd like to be able to switch between two possible JPanels in my frame by selecting a certain JMenuItem. What I tried so far:
Action listener in my JMenuBar class:
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(fullList))
gui.switchToFullList();
else if (e.getSource().equals(history))
gui.switchToHistory();
}
In GUI class:
void switchToFullList() {
remove(history);
add(fullList);
}
void switchToHistory() {
remove(fullList);
add(history);
}
where history and fullList are JPanels.
This doesn't seem to modify my frame in any way.
If you want to show one Panel and hide another, they both should ba childreen of your Frame, then you can acces those Panels by: frame.JpanelName.
Example of removing history and adding fullList:
frame.remove(frame.history);
frame.getContentPane().add(frame.fullList);
frame.validate();
frame.repaint();
Related
I have a reference to a JPanel that is stored inside a JFrame. I tried attaching a ComponentAdaptor to the JPanel, but when I move the JFrame, it is not getting called. Any ideas on how I can detect when the JPanel moves on the screen if all I have is a reference to the JPanel and not the JFrame?
This is my adaptor:
private class Listener extends ComponentAdapter {
#Override
public void componentMoved(ComponentEvent e) {
if (e.getComponent().equals(target)) {
targetMoved();
} else {
stickyMoved();
}
}
}
I think AncestorListener is what your looking for.
The JPanel does not move, but the frame that contains it does. You can use an AncestorListener on the panel, instead of ComponentListener to be notified when such events happen on any parent components.
private class Listener implements AncestorAdapter {
#Override
public void ancestorMoved(ComponentEvent e) {
if (e.getComponent().equals(target)) {
targetMoved();
} else {
stickyMoved();
}
}
}
how I can detect when the JPanel moves on the screen if all I have is a reference to the JPanel and not the JFrame?
You can get a reference to the JFrame by using:
SwingUtilities.windowForComponent( panel );
Of course you won't know which frame until the panel has actually been added to the frame. You can use an AncestorListener as demonstrated in Dialog Focus to know when the panel is actually visible.
Then you can add your ComponentListener to the frame.
Currently I have a client that contains two panels... one is the main game and the other is a side panel containing tools. The side panel can be shown/hid (thus making the frame only show the game).
activateSidePanel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (sp) {
frame.remove(enhancedPanel);
frame.repaint();
frame.pack();
sp = false;
} else if (!sp) {
frame.add(enhancedPanel);
frame.repaint();
frame.pack();
sp = true;
}
}
});
That is my action listener for the button. The button hides correctly, however it doesn't show. When I click the button again it just makes the frame smaller and does not bring back the side panel. Confused on this one.
} else if (!sp) {
Why do test for !sp? A boolean can only have two values, so all you need is an if/else statement (without the test on the else.
Instead of removing/adding the panel I would try invoking the setVisible(false/true) method first.
If that doesn't work then then general code for removing/adding components is:
panel.add(...)
panel.revalidate();
panel.repaint();
You should not need to invoke pack() because you don't want the frame to keep resizing, you only want the main panel to become bigger/smaller.
I am planning to make a program that in the top of the contentPane has a menubar.
Under this menubar another JPanel, here is what I did (it works), but I don't know if this is the best way:
I made a lot of JPanels with different buttons, I want that a JMenuItem changes the screen(JPanel)
So what I did for each JMenuItem that set the specific JPanel(all panels are in the same position in the GridBagLayout, but all start with .setVisible(false);)
jemnuitem1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(true);
jpanelItem2.setVisible(false);
jpanelItem3.setVisible(false);
}
});
jemnuitem2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(false);
jpanelItem2.setVisible(true);
jpanelItem3.setVisible(false);
}
});
jemnuitem3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jpanelItem1.setVisible(false);
jpanelItem2.setVisible(false);
jpanelItem3.setVisible(true);
}
});
This works, but I want to know if there is a way better to do this, or can I have a big problem doing this, because if this works, its fine for me work in this way, but I want the help of others that already made something similar.
You should use CardLayout. Then you can switch the visible panel instead of writing clumsy code like you have now.
I am creating a java application which consists of two frames(JFrame1 and JFrame2)
JFrame1 has a grid 6x6 button; and JFrame2 has 6 radio buttons representing colours. How can I link the two frames so that when a button in JFrame1 is clicked, JFrame2 pops up and when a colour is chosen from that the JFrame2 closes and the clicked button gets the respective colour?
It is better to have one JFrame for every application. Use one for the 6x6 JButtons and create a modal JDialog for your color JRadioButtons.
The color selection JDialog should have a public getSelectedColor() method in order to return the selected color to the caller class.
Instantiate the ColorDialog in main and do not set it visible.
The ActionListener of each JButton should make the modal JDialog visible.
The RadioButton ActionPerformed should set the selected color and make the JDialog invisible.
Call getSelectedColor() and apply the returned color to your JButton.
In your frame1's button action listner, you can do something like this
public void actionPerformed(ActionEvent e) {
Frame2 frame = new Frame2(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
where "this" refers to the frame1 object. This is you can access its jTEXTFIELD and jBUTTONs from the second frame. So naturally you have store it in Frame1 object declared in your second class.
Suppose you have a clickable color field in frame2 object, once you click on it, you should trigger a function that get the input field from frame1 (using your locale object reference) and store it in it. something like this:
public void actionPerformed(ActionEvent e) {
frame1.getMyTextField().setText(WHAT_THE_CLICKED_ON);
this.close();
}
Sorry if I made any syntax errors, it's been a long time I didnt work with java :)
Just create another class, let us say FrameMananger, then use the singleton pattern to manage them.
Then in any class, you can use FrameManager.getFrame1() to get the frame1, same as the frame2. You can add logic judgement inside, like dynamically dispose some frame or only create them when needed.
This issue is fairly common concept when you create a game and try to navigate between your every view(like the show score panel from everywhere).
public class FrameManager
{
Frame1 frame1;
Frame1 frame2;
public static Frame1 getFrame1()
{
if(frame1 == null)
frame1 = new Frame1();
return frame1;
}
public static Frame1 getFrame2()
{
if(frame2 == null)
frame2 = new Frame1();
return frame2;
}
public class Frame1 extends JFrame
{
}
public class Frame2 extends JFrame
{
}
}
I'm having trouble with getContentPane() in my GUI.
public class CryptoMainMenu extends JPanel implements ActionListener {
public CryptoMainMenu()
{
Templates template = new Templates();
//setting up the primary panel
primaryPanel = new JPanel();
primaryPanel.setLayout(new BorderLayout());
//setting up algorithm button
algorithm = new JButton("Algorithm");
algorithm.addActionListener(this);
add(primaryPanel);
setSize(730, 400);
}
}
public class CryptoCategoriesMenu extends JFrame implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == back)
{
CryptoMainMenu main = new CryptoMainMenu();
main.setVisible(true);
this.setVisible(false);
}
}
}
In CryptoMainMenu if I'm extending JPanel I can't use getContentPane().add(primaryPanel), but if I just have add(primaryPanel), then my program isn't working because I linked all of my GUI classes together, so that when it gets to CryptoCategoriesMenu, and if I try pressing the JButton back, CryptoMainMenu shows as blank window. Is there something similar to getContentPane() that I can use with JPanel?
Edit:
This is suppose to a menu type GUI. In CryptoMainMenu, it displays a GUI where the user can press a button and it leads to another GUI which is CryptoCategoriesMenu. In CryptoCategoriesMenu, it shows another set of buttons and one of them is back. When I just have add() and I press back, CryptoMainMenu doesn't show up and that's the problem I'm having.