Panel components disappear when I minimize frame - java

I have a layout with a main panel whose content is decided by me throught buttons in this way:
public void actionPerformed(ActionEvent e) {
mainPanel.removeAll(); //removing all current panel components
if(e.getActionCommand().equals("content1")){
mainPanel = new Content1Panel();
add(mainPanel,BorderLayout.CENTER);
validate();
}else if(e.getActionCommand().equals("content2")){
mainPanel = new Content2Panel();
add(mainPanel,BorderLayout.CENTER);
validate();
}
}
now, if I minimize the frame and then bring it to front I find all main panel's components disappeared! Anyway, when I hover on them with the mouse components show again.
What is wrong?

for JFrame / JDialog / JWindow
to use
validate(); (revalidate in Java7 )
repaint();
example about standard rulles
use CardLayout instead of remove and then add the JPanel to the container

Related

java: Why does frame get the event of a component

I have a JFrame, which contains just a JPanel.
I add an mouse event to the JPanel.
But the whole JFrame gets the same mouse event.
Here is my code:
public class TestSwing extends JPanel {
public TestSwing() {
super.setSize(20, 20);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
System.out.println(me);
}
});
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new TestSwing());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
I set the size of the JPanel (20, 20), but no matter where I click, the mouse event will always be triggered.
You're adding that JPanel to the JFrame's contentPane, a component that uses BorderLayout, a layout which does not respect size or even for the most part preferred size, and so the JPanel will fill the entire JFrame's contentPane. Give the contentPane a FlowLayout and set the JPanel's preferred size and you'll see a difference. In the future, give the JPanel a Border to see its boundaries. This will make debugging this easy.
If you don't tell it otherwise, your JFrame will have BorderLayout like this:
Now if you furthermore don't tell your Panel where to go, it wil go into CENTER and thus be resized to fill whole content area.
For checking MouseEvent on only one JPanel I suggest you add another JPanel (maybe with different background?) to other area:
frame.getContentPane().add(new TestSwing(), BorderLayout.CENTER);
JPanel left = new JPanel();
left.setBackground(Color.red);
frame.getContentPane().add(left, BorderLayout.LEFT);
Size set by setSize() is only valid until it's recalculated based on Layout and other properties.

Java Swing JFrame minimize/maximize resize bug

The problem is that when I try to maximize the JFrame the frame does get maximized, but the content size is preserved.
http://i.imgur.com/7q5Yh9F.png
My main frame class:
private CardLayout layout;
private SettingsFrame settingsFrame;
private Container contentPane;
Frame frame = this;
private ApplicationFrame() {
contentPane = getContentPane();
layout = new CardLayout();
contentPane.setLayout(layout);
initializeFrame();
settingsFrame = new SettingsFrame(model);
initializeMenuBar();
initializePanels();
showPage(FIRST_PAGE);
this.addWindowStateListener(listener);
}
public SettingsFrame getSettingsFrame() {
return settingsFrame;
}
private void initializeFrame() {
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setTitle(APPLICATION_TITLE);
this.settingsFrame = new SettingsFrame(model);
this.setSize(1400, 900);
this.setLocationRelativeTo(null);
}
private void initializePanels() {
add(new Panel(), FIRST_PAGE);
add(new Panel(), SECOND_PAGE);
add(new Panel(), THIRD_PAGE);
}
I tried to make a listener, catch the maximize event and there i tried:
revalidate();
repaint();
also
invalidate();
validate();
but with no succes.
I found out that:
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
is corectly maximizing the Frame, but i cannot use that is the listener because the maximize event already happened.
You're using a CardLayout which unfortunately won't allow you to resize the JComponent. Because the CardLayout can hold/manage one or more components that share the same display space.
You should add a JPanel and set that panel's layout to the CardLayout if you wish to use it.
I strongly recommend reading the following documentation: A Visual Guide to Layout Managers

Swing: Start second JPanel, when the first JPanel is clicked

I'm writing a simple java game and I'm facing this problem:
My different layouts are in different JPanels (1 JPanel for the welcoming page, where I have to press 'start game' and another one with the actuall functionallity)
I start the game from a JFrame
import javax.swing.JFrame;
public class RType extends JFrame {
public RType() {
add(new Welcome());//first panel
add(new Board());//panel with the game
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(100, 100);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new RType();
}
}
obviuosly, this launches the second panel right after the first, and I cant see the first one.
I've tried some stuff, trying to invoke the second panel in the main method, when the first panel is clicked that way:
RType rt=new RType();
rt.add(new Board()); //in this case add(new Board()); is removed from constructor
but it's doing nothing.
how can I solve it?
As #nachokk has said, you should be using a CardLayout instead. It lets you do things like tabs in a browser, but you don't need to make the tabs visible for your game if you don't want to. You make your welcome "card" visible at first, then when the user clicks you switch to the Board "card".
I don't recommend to add directly to the JFrame components, instead use another container as JPanel . JFrame default layout is BorderLayout, when you add in the way you are adding it always put in the center.
Make something like this:
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new CardLayout());
mainPanel.add(new Welcome(), "Welcome");
mainPanel.add(new Board(),"Board");
frame.add(mainPanel);
Here is a tutorial How to use CardLayout
on first panel of welcome add a button, and apply actionperformed like
JButton myButton = new JButton("Add Component ");
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.remove(welcome);
frame.add(Board, BorderLayout.CENTER);
frame.revalidate();
frame.repaint();
}
});
By default, both panels will fill up the entire Frame's area. To fix this, you will need to use another layout, such as a GridLayout to structure the areas in which the panels will take up the Frame's area.
You can also go with no layout to hard code the pixel values of where you want the panels to fit in your frame.
EDIT: Based on what you're looking to do, the CardLayout is probably what you'll want to use for your Frame's layout.

placing a transparent JPanel on top of another JPanel not working

I am trying to place a JPanel on top of another JPanel which contains a JTextArea and a button and i want to the upper apnel to be transparent. I have tried it by making the setOpaque(false) of the upper panel. but it is not working. Can anyone help me to get through this? Thanks in advance!
public class JpanelTest extends JPanel
{
public JpanelTest()
{
super();
onInit();
}
private void onInit()
{
setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextArea(100,100),BorderLayout.CENTER);
panel.add(new JButton("submit"),BorderLayout.SOUTH);
JPanel glass = new JPanel();
glass.setOpaque(false);
add(panel,BorderLayout.CENTER);
add(glass,BorderLayout.CENTER);
setVisible(true);
}
public static void main(String args[])
{
new JpanelTest();
}
}
Indeed, it would be useful to tell the reason why you want panels one over another.
Starting with your code, and changing it a lot, I got it to work, but it might not do what you expect...
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{
public Test()
{
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 200);
onInit();
setVisible(true);
}
private void onInit()
{
JLayeredPane lp = getLayeredPane();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextArea(), BorderLayout.CENTER);
panel.add(new JButton("Submit"), BorderLayout.SOUTH);
panel.setSize(300, 150); // Size is needed here, as there is no layout in lp
JPanel glass = new JPanel();
glass.setOpaque(false); // Set to true to see it
glass.setBackground(Color.GREEN);
glass.setSize(300, 150);
glass.setLocation(10, 10);
lp.add(panel, Integer.valueOf(1));
lp.add(glass, Integer.valueOf(2));
}
public static void main(String args[])
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Test();
}
});
}
}
If totally transparent, well, it is like it isn't here! When opaque, it just covers some of the GUI, but doesn't prevent mouse clicks, for example.
1) there are a few ways, there no issue to put JPanel, with covering full JFrames/JPanel area or only part of Rectangle / Dimension that returns JFrames/JPanel
use JLayer(Java7) based on JXLayer (Java6)
use GlassPane
use JViewport
use OverlayLayout
use transucent JDialog / JWindow
2) everything depends of if you want to protect against mouse and key events from the top layer to bottom, or not (to avoiding redispatch events from - to and vice versa)
Check out this tutorial on using Swing Root Panes.
The glass pane is useful when you want to be able to catch events or paint over an area that already contains one or more components. For example, you can deactivate mouse events for a multi-component region by having the glass pane intercept the events. Or you can display an image over multiple components using the glass pane.

Java GUI - JPanels, JFrames, JButtons

I'm trying to open a window that has both an image and buttons in it. But I can't seem to figure out how to add the button. The image displays great and the menu works fine, but no matter where I add the button (into the JLabel, JPanel, or JFrame), it doesn't ever show...
Main:
public static void main(String[] args) {
GUI myGUI = new GUI();
myGUI.show();
}
GUI class: openImage is called when using the menu. The image then displays, but no button.
private JFrame myFrame;
private JPanel myPanel;
private JLabel myLabel;
public GUI()
{
myFrame = new JFrame();
initializePanel();
}
public void show()
{
myFrame.setSize(600,600);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.addMouseListener(this);
setupMenu(myFrame);
myFrame.setVisible(true);
}
private void initializePanel()
{
myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(500,500));
//myPanel.setLayout(new BorderLayout());
}
private void openImage(String fileName)
{
try {
myImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myLabel = getJLabel();
JButton button = new JButton("ButtonClick");
button.addActionListener(this);
myFrame.setContentPane(myLabel);
myPanel.add(button);
myFrame.getContentPane().add(myPanel);
myFrame.pack();
myFrame.setSize(600,600);
}
private void setupMenu(JFrame window) {
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem open = new JMenuItem("Open");
open.addActionListener(this);
file.add(open);
menubar.add(file);
window.setJMenuBar(menubar);
}
Your main issue is your setting the contentPane to be a JLabel -- don't do this! The contentPane needs to be opaque, needs to be built to be easily used as a Container and in your case, really should be a JPanel. JLabel I believe uses a null layout so it's no surprise that your code shows no button. If you want to show a background image, make have myPanel constructed from an anonymous class that extends JPanel, override the paintComponent method in this class (calling super.paintComonent first in the method), and draw the image in this method. Then you can add components to the contentPane which will now use a FlowLayout (the default for a JPanel) and it will be opaque by default.
Also, if your goal is to swap items displayed in your GUI, use a CardLayout to do the swapping for you as this layout makes swapping components a breeze.
really don't know, depends of method(s) how you are added picture to the JLabel, JPanel, or JFrame, but maybe for simle Container that contains a few, only one-two JComponents is there crazy idea, without side effects, with idea to display picture and to add there JButton:
JLabel is very similair JComponent to the JPanel, and is by default translucent and very simple implements Icon/ImageIcon, then you'll only to call myLabel.setIcon(myPicture)
to the all of JComponents you are/could be able to add another JComponent by using some of LayoutManager (Box, Flow, GridBagLayout)
You tried to set the label as the content pane and then tried to add the panel to that image which doesn't make sanse at all.
Change it so you add the label to the panel and have the panel as content pane:
Like this:
You have this line which is the problem. It doesn't make much sense:
myFrame.setContentPane(myLabel);
Try instead:
myFrame.getContentPane().add(myLabel);

Categories