I want to know how can I switch JPanels inside my main JFrame, I have tried this code but when I click the menu item it changes then I click other menu item and does not change, I click the menu Item I clicked first and it changes ....is there other way I can easily switch jpanels? do not show me the cardLayout crap because it doesn't work with what i need and it seems that every answer on google involves that demo, anyway if there is a simple way of doing things I appreciate it if someone helps me point in the right direction thanks.
menuItem.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainPane.remove(getContentPane());
mainPane.add(cdPanel, BorderLayout.CENTER);
mainPane.validate();
}
});
there are two ways
remove (JFrame.getContentPane.removeAll()) and add JPanel to JFrame, required to call JFrame.(re)validate and JFrame.repaint after all changes to already visible Swing GUI is done, once time, last code lines
(better, correct, proper of ways) use CardLayout, code example in official Oracle tutorial, a few good, some excelent examples here
Edited Code:
public static void main(String[] args)
{
// TODO code application logic here
JFrame frame = new JFrame();
frame.setSize( 300, 300);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JPanel panelOne = new JPanel();
panelOne.setBackground( Color.red );
JPanel panelTwo = new JPanel();
panelTwo.setBackground(Color.blue);
frame.setContentPane( panelOne );
frame.setVisible(true);
//This delay is just here so you can see the transition
try
{
Thread.sleep( 1000 );
}
catch ( InterruptedException ie )
{
ie.printStackTrace();
}
panelTwo.setSize( frame.getContentPane().getSize() );
frame.setContentPane( panelTwo );
}
I would like to point out that there is a class called JTabbedPane. It might not be what you're looking for, but it's essentially one pane, with multiple tabs on it that a user can click and switch views.
http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html
http://docs.oracle.com/javase/6/docs/api/javax/swing/JTabbedPane.html
Related
I have recently begun working with JComponents to create GUI systems. Everything is working but the bottom and right sides of the JFrame do not get painted over and remain white.
Screenshot of running GUI:
In the screenshot you can see the 'drknBtn' is displayed correctly; this is because I hovered over it with the mouse before taking the picture. Hovering over the buttons refreshes them and they appear as normal. Due to this, I would assume the panel that holds them, 'bottomPnl' is covering that white space, but that panels background is not showing at the bottom portion. Any ideas on what could cause this? I have tried calling 'bottomPnl.repaint()' directly before calling pack(), but no change.
My code is below.
Note: For each JComponent, I created a class extending that component. This way I could set default values for the components in the constructors of these classes instead of doing each one individually. I'll list the relevant properties of the Frame and Panels.
Frame: setSize(width,height); setResizeable(false); setLocationRelativeTo(null);
Panel: setLayoutManager(from contructor); setPreferredSize(new Dimension(width,height)); same for setMinimumSize and setMaximumSize.
public Display(String title, int w, int h){
width=w;
height=h;
frame = new FrameUI(title,w,h);
//parent panel
parentPnl= new PanelUI(width,height, new FlowLayout(FlowLayout.CENTER,0,0));
parentPnl.setBackground(new Color(100,175,175));
//top panel
topPnl= new PanelUI(width,(int)(height*.15), new FlowLayout(FlowLayout.CENTER,0,0));
topPnl.setBackground(new Color(100,175,175));
chooseFileBtn = new ButtonUI("Browse...",topPnl.getWidth()/4,(int)(topPnl.getHeight()*.9),new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
fc = new FileChooserUI();
fc.setFileFilter(new FileNameExtensionFilter("Image files", ImageIO.getReaderFileSuffixes()));
int result = fc.showOpenDialog(null);
try {
if (result == JFileChooser.APPROVE_OPTION) {
picture.setIcon(new ImageIcon(ImageIO.read(fc.getSelectedFile()).getScaledInstance(picture.getWidth(),picture.getHeight(), 0)));
}
} catch (Exception iOException) {
}
}
});
//middle panel
midPnl= new PanelUI((int)(width*.85),(int)(height*.7), new FlowLayout(FlowLayout.CENTER,0,0));
midPnl.setBackground(new Color(75,125,125));
picture = new LabelUI("",midPnl.getWidth(),midPnl.getHeight());
picture.setBackground(new Color(75,125,125));
picture.setVisible(true);
picture.setOpaque(true);
picture.setIcon(null);
//bottom panel
bottomPnl= new PanelUI(width,(int)(height*.15), new FlowLayout(FlowLayout.CENTER,0,0));
bottomPnl.setBackground(new Color(100,175,175));
ltnBtn = new ButtonUI("Lighten Picture",bottomPnl.getWidth()/3,(int)(bottomPnl.getHeight()*.9),new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
}
});
ltnBtn.setBackground(Color.LIGHT_GRAY);
ltnBtn.setForeground(Color.BLACK);
drknBtn = new ButtonUI("Darken Picture",bottomPnl.getWidth()/3,(int)(bottomPnl.getHeight()*.9),new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
}
});
drknBtn.setBackground(Color.DARK_GRAY);
drknBtn.setForeground(Color.WHITE);
//add UI Objects
topPnl.add(chooseFileBtn);
midPnl.add(picture);
bottomPnl.add(ltnBtn);
bottomPnl.add(drknBtn);
parentPnl.add(topPnl);
parentPnl.add(midPnl);
parentPnl.add(bottomPnl);
Container contentPane = frame.getContentPane();
contentPane.add(parentPnl);
frame.pack();
frame.setVisible(true);
}
}
topPnl= new PanelUI(width,(int)(height*.15), new FlowLayout(FlowLayout.CENTER,0,0));
looks to me like you are manually trying to control the size of the panels and therefore the size of the components added to your panels. Your calculations are wrong and some components aren't displayed properly. Also all your sizes are fixed at creation time and will not adjust if the size of the frame ever changes.
Don't try to control the sizes manually. Use layout managers to dynamically size components based on the properties of the component.
I fail to see why you would want a button to be 15% of the space available to the frame.
If you want the button to be larger than normal you can set extra empty space around the text of the button by using:
button.setMargin( new Insets(50, 50, 50, 50) );
Then just add the button to a panel using a FlowLayout and let the layout manager do its job.
The default layout for a frame is a BorderLayout, so you can then add the "topPnl" to the frame using:
frame.add(topPnl, BorderLayout.PAGE_START);
The other panels can then be added using:
frame.add(midPnl, BorderLayout.CENTER);
frame.add(bottomPnl, BorderLayout.PAGE_END);
This is how Swing was designed to be used with layout managers.
Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples.
The main point is use methods like setMargin(...), to provide hints to the component on what their preferred size should be.
I fixed the problem by removing the 'setSize()' method in the FrameUI constructor. However, I still do not understand how you could dynamically size panels as you said while still maintaining the proportions I want for them. Thank you #camickr for the pointers, my original problem is fixed. I'll look into more javadocs and tutorials on layout managers and such.
I am trying to enter an event for JButon I create:
JButton botton1=new JButton("welcom to my show db! lets start");
botton1.setFont(new Font ("Eras Medium ITC",Font.BOLD,20));
this.add(botton1);
JPanel Basic_panel=new JPanel();
Basic_panel.setName("SHOW DB ");
Basic_panel.setBounds(x,y,width,hight);
botton1.addActionListener(this) ;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource()==botton1){
Now I want to enter another JFrame I made, and make the first disappear. How?
For your original question:
How to add action to a button?
you might want to check How to write an Action Listener.
For your second question:
Now I want to enter another JFrame I made, and make the first disappear. How?
please check both approaches :)
Option 1 (Recommended)
If you want to do it the right way, you should use a CardLayout as recommended by #AndrewThompson in his comment above.
I also saw you were using a Null Layout (because of setBounds() method), you might also want to get rid of it, see Why is it frowned upon to use a null layout in Swing? and Null Layout is Evil to know why, insted you should be using a Layout Manager or combinations of them as shown in the following code based on #AndrewThompson's answer (The same that was linked in his comment above) but a bit modified to work with a JFrame instead of a JOptionPane, so give him credit by upvoting his Original Answer too!
This produces the following outputs:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CardLayoutDemo {
JButton button1, button2;
CardLayoutDemo() {
JFrame gui = new JFrame("CardLayoutDemo");
button1 = new JButton("Go to pane 2");
button2 = new JButton("Go to pane 1");
JPanel pane1 = new JPanel();
pane1.setLayout(new BoxLayout(pane1, BoxLayout.PAGE_AXIS));
JPanel pane2 = new JPanel();
pane2.setLayout(new BoxLayout(pane2, BoxLayout.PAGE_AXIS));
final CardLayout cl = new CardLayout();
final JPanel cards = new JPanel(cl);
pane1.add(new JLabel("This is my pane 1"));
pane1.add(button1);
pane2.add(new JLabel("This is my pane 2"));
pane2.add(button2);
gui.add(cards);
cards.add(pane1, "frame1");
cards.add(pane2, "frame2");
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == button1) {
cl.show(cards, "frame2");
} else if (ae.getSource() == button2) {
cl.show(cards, "frame1");
}
}
};
button1.addActionListener(al);
button2.addActionListener(al);
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.pack();
gui.setVisible(true);
}
public static void main(String[] args) {
new CardLayoutDemo();
}
}
With this option you only have 1 JFrame but you can change through different views, and you don't annoy user with multiple windows on the task bar.
One more tip here is: If you're going to open this second JFrame to prevent user from doing something on the 1st one, you should consider using a JOptionPane or this second JFrame will contain just a bit information which you don't want to have there for the whole time (Something like a pop up).
Option 2 (Not recommended)
But if you really really really want to use multiple JFrames (which is not recommended) you can dispose() it. At the time you're calling your new JFrame to be created. For example, the following code produces this output:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TwoJFrames {
JFrame frame;
JButton button;
TwoJFrames() {
frame = new JFrame("1st frame");
button = new JButton("Click me!");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new AnotherFrame();
frame.dispose();
}
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
new TwoJFrames();
}
class AnotherFrame {
JFrame frame2;
JLabel label;
AnotherFrame() {
frame2 = new JFrame("Second Frame");
label = new JLabel("This is my second frame");
frame2.add(label);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.pack();
frame2.setVisible(true);
}
}
}
In this case you might want to consider setVisible() instead if you want to go back to previous state or reopen this one when closing the second JFrame
Both of my above codes are called a Minimal, Complete, and Verifiable example (MCVE) or Runnable Example or Short, Self Contained, Correct Example (SSCCE) which are code you can copy-paste and see the same output as me, when you have an error in your code, these examples are very handy because we can see where your errors are or be able to find them easier and/or faster.
You should consider reading all the links I provided (included these ones) and for your future questions to make something like I've done above, that way you'll prevent confusion and you'll get more, faster and better responses.
I just created a GUI, now I want to create another GUI and link both together.
So on the first GUI when the user selects 'next' button, the second GUI is displayed.
For this, do I have to create a new class and just create a GUI again?
Here is what I have now:
import java.awt.Color;
import javax.swing.*;
public class Wizard {
private JLabel lblPicture;
private JRadioButton btLdap, btKerbegos, btSpnego, btSaml2;
private JButton btNext;
private JPanel panel;
public static void main(String[] args) {
new Wizard();
}
public Wizard() {
JFrame frame = new JFrame("Wizard");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,360);
frame.setVisible(true);
MyPanel();
RadioButtons();
Button();
Image();
groupButton();
frame.add(panel);
frame.setVisible(true);
}
public void MyPanel() {
panel = new JPanel();
panel.setLayout(null);}
public void RadioButtons() {
btLdap = new JRadioButton ("Ldap");
btLdap.setBounds(60,85,100,20);
panel.add(btLdap);
btKerbegos = new JRadioButton ("Kerbegos");
btKerbegos.setBounds(60,115,100,20);
panel.add(btKerbegos);
btSpnego =new JRadioButton("Spnego");
btSpnego.setBounds(60,145,100,20);
panel.add(btSpnego);
btSaml2 = new JRadioButton("Saml2");
btSaml2.setBounds(60,175,100,20);
panel.add(btSaml2);
}
public void Button() {
btNext = new JButton ("Next");
btNext.setBounds(400,260,100,20);
panel.add(btNext);
}
public void Image() {
ImageIcon image = new ImageIcon("image.jpg");
lblPicture = new JLabel(image);
lblPicture.setBounds(200,20, 330, 270);
panel.add(lblPicture);
}
private void groupButton() {
ButtonGroup bg1 = new ButtonGroup( );
bg1.add(btLdap);
bg1.add(btKerbegos);
bg1.add(btSpnego);
bg1.add(btSaml2);
}
}
To display another window, you would create the window, be it a JFrame, JDialog, or what have you, and call setVisible(true) just like you do for your first window.
You ask if your other "window" should be in another class, and likely that answer is yes. Since it will have a completely different set of behaviors and goals from the first class, better to separate out concerns.
Having said that, what you plan to do, to show multiple windows is not always the best user interface design. Better often is to show multiple views using a container that uses a CardLayout.
If you want to display another window in a modal fashion, that is, have the first window wait for the second window to be processed before allowing user interaction, the second window should be a modal JDialog or JOptionPane (a JDialog in disguise).
I think for what you want to achieve, the use of a CardLayout would be appropriate.
This enables you to have multiple panels within the one frame with only one panel visible at a time and has functionality to 'flip' through the panels like a 'deck of cards'. So on initialising your frame you create the panels you want, and specify which one to start at then your next button will go to the next panel in the list.
See the tutorial here there are also some video tutorials available on youtube.
Write the two GUI's in different classes. When you start your program, start the first GUI.
FirstGUI frame1 = new FirstGUI("Title text");
frame1.setVisible(true);
Then, in the action listener code for the button you call "next"...
frame1.setVisible(false); //if you want to save the frame
frame1.dispose(); //if you want to kill the frame
SecondGUI frame2 = new SecondGUI("Title text");
frame2.setVisible(true);
I'm having a little trouble with my project.
I have one class that is a panel displaying 4 buttons.
I have 4 classes(only one so far) that are panels displaying various components. These panels will occupy one space and only one panel should be visible at a time.
What I want to do is to control the visibility of the panels with their respective button.
For example, when the user clicks on button1, panel1 should appear, and when button2 is pressed, panel2 appears, etc.
This is my first time working with a GUI in java and any help is appreciated.
These are the options before you, (Given in the order I guess the most suitable for you)
CardLayout
A CardLayout object is a layout manager for a container. It treats each component in the container as a card. Only one card is visible at a time, and the container acts as a stack of cards.
for more info see How to Use CardLayout
JTabbedPane
A component that lets the user switch between a group of components by clicking on a tab with a given title and/or icon
for more info, see How to Use Tabbed Panes
JDialog(Maybe an undecorated one)
for more info see How to Make Dialogs
CardLayout is the best option for your requirement.
http://www.java2s.com/Code/Java/Swing-JFC/CardLayoutDemo.htm
As with the other answers, in a recent GUI I created I used CardLayout to accomplish this task.
The solution is simple, have one panel in your Parent JFrame that will hold the CardLayout and when you add each panel you want to show you associate a String with it so you can grab it later such as:
panelManager.add(typeSelectionView, TYPEVIEW);
Where panelManager is my JPanel containing my layout (Which you have to add before this so you can use this add() method.
Ensure you are storing these Strings which identify your hidden panels in some form, as I have here with my final variables, and when it comes time to show this panel which is hidden within the layout simply call:
cl.show(panelManager, newPanel);
Where in my case, newPanel was calculated by the controller and handed down to the view. It uses the final Static Strings in the view's Class.
Although CardLayout is already suggested, and even a link to the Swing tutorial already provided, I will add some sample code which makes use of the CardLayout as an answer.
public class CardLayoutDemo {
private static JFrame createGUI(){
JFrame testFrame = new JFrame( );
testFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
List<String> layoutConstraints = Arrays.asList( "first", "second", "third");
final JPanel contentsPane = new JPanel( );
final CardLayout cardLayout = new CardLayout( );
contentsPane.setLayout( cardLayout );
//listener which will be used to switch between the different layouts
ActionListener listener = new ActionListener() {
public void actionPerformed( ActionEvent aActionEvent ) {
String constraint = aActionEvent.getActionCommand();
cardLayout.show( contentsPane, constraint );
}
};
//add components to card layout with specific constraint
for ( String constraints : layoutConstraints ) {
contentsPane.add( new JLabel( constraints ), constraints );
}
//create buttons allowing to switch between the different layouts
JPanel buttonPanel = new JPanel();
for ( int i = 0; i < layoutConstraints.size(); i++ ) {
String constraint = layoutConstraints.get( i );
JButton button = new JButton( "Layout " + i);
button.setActionCommand( constraint );
button.addActionListener( listener );
buttonPanel.add( button );
}
testFrame.add( contentsPane, BorderLayout.CENTER );
testFrame.add( buttonPanel, BorderLayout.SOUTH );
return testFrame;
}
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
public void run() {
JFrame frame = createGUI();
frame.pack();
frame.setVisible( true );
}
} );
}
}
I want to make a loading message when an app processes, so I used a JPanel over a JTree. But when the user clicks on the JPanel, the JTree will be selected and the JPanel will go to the back. After hiding the JPanel, it never shows again. I don't know why, but it seems it never go in front of the JTree.
I need a way to bring the JPanel in front of everything. How can I do this?
EDIT: Also I must mention that I don't want a JDialog. I want to use the JPanel on top of any element to show a loading message until a process finishes.
So here you have at least two solutions. Either go with what #Geoff and #sthupahsmaht are suggesting. BTW also possible is to use JOptionPane which automatically creates a dialog for you.
The other option would be to use a GlassPane from a frame.
Or yet another option is to use JLayeredPane as #jzd suggests.
EDIT:
Example showing how to use GlassPane to capture user selections.
Try following steps:
1.Left clicking on the glass pane visible at start. See the output.
2.Right click it. This hides the glass pane.
3.Left clicking on the content pane. See the output.
4.Right click it. Go to point 1.
Enjoy.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class OverPanel extends JPanel
{
private static void createAndShowGUI()
{
final JFrame f = new JFrame();
f.setPreferredSize(new Dimension(400, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel glassPanel = new JPanel();
glassPanel.setBackground(Color.RED);
glassPanel.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
super.mousePressed(e);
System.out.println("f.getGlassPane() mousePressed");
if(e.getButton() == MouseEvent.BUTTON3)
f.getGlassPane().setVisible(false);
}
});
f.setGlassPane(glassPanel);
f.getContentPane().setBackground(Color.GREEN);
f.getContentPane().addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
super.mousePressed(e);
System.out.println("f.getContentPane() mousePressed");
if(e.getButton() == MouseEvent.BUTTON3)
f.getGlassPane().setVisible(true);
}
});
f.getGlassPane().setVisible(true);
f.pack();
f.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
}
EDIT2:
If you want to have an effect of a dialog, you can achieve it by incorporating appropriately this code into my example.
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
panel.setBackground(Color.YELLOW);
panel.add(new JLabel("I am message Label"));
panel.add(new JButton("CLOSE"));
JPanel glassPanel = new JPanel(new GridBagLayout());
glassPanel.setOpaque(false);
glassPanel.add(panel);
You need a to use a JLayeredPane for moving components in front of each other.
Here is a tutorial: How to use Layered Panes
Disabled Glass Pane might help you out.
It's not really clear how your code is organized. However, it sounds like what you might want is a modal dialog. Here's a link to a similar discussion with a number of referenced resources.
How to make a JFrame Modal in Swing java
Use JXLayer or JIDE Overlayable.
Jpanel main = new JPanel();
Jpanel a = new JPanel();
JPanel b = new Jpanel();
main.add(a);
main.add(b);
at this point the object:
a -> 0 ( index)
b -> 1 (index)
main.getComponentCount() = 2
main.setComponentZorder(b,0);
a -> 1
b -> 0;
b OVER
a DOWN
For those who have no problem using a JDialog, this is a sure way to get it to show up if you're having issues. Just make sure to control it properly if the dialog is modal, when disposing, setting focus etc.
JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);