There's a simple application that uses JScrollPane for 2 lists and have 1 button to switch them. I want to add many more Swing elements, but I cannot move them with object.setBounds. Whatever I will write in this method element doesn't change its place and size.
package paka;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;;
public class Question extends JFrame {
private JList leftlist,rightlist;
private JButton movebutton;
private JLabel pointlessLabel;
private static String[] foods={"bacon","wings","ham","beef","more bacon"};
public Question(){
super("title");
setLayout(new FlowLayout());
leftlist=new JList(foods);
leftlist.setVisibleRowCount(3);
leftlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
add(new JScrollPane(leftlist));
movebutton = new JButton("Move");
movebutton.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
rightlist.setListData(leftlist.getSelectedValues());
}
}
);
add(movebutton);
rightlist = new JList();
rightlist.setVisibleRowCount(3);
rightlist.setFixedCellWidth(100);rightlist.setFixedCellHeight(15);
rightlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
add(new JScrollPane(rightlist));
//Okay, deleting everything below we have only two list with button that moves elements from 1st list to 2nd
movebutton = new JButton("Click me!");
movebutton.setBounds(700, 100, 80, 20);
add(movebutton);
pointlessLabel = new JLabel("I'm unbreakable");
pointlessLabel.setBounds(500,200,100,50);
add(pointlessLabel);
}
public static void main(String args[]){
Question go = new Question();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(300,200);
go.setVisible(true);
}
}
You need to use combinations of Layout Managers (as stated by #AndrewThompson on his comment above) to achieve the same output that you have with a null layout.
Avoid the use of null layout, see: Null layout is evil and Why is it frowned upon to use a null layout in Swing?
With the code below you can have the same output you had with setBounds() method. I didn't added an ActionListener to this code, since I'm just demonstrating how to stop using null layout and have the same output. Yes! The second one seems shorter, that's because of pack() but you can still setSize() if you want / need an specific window size.
To add more elements below just add more JPanels and add them to pane, I hope this helps to solve your issue, and if not, please post a Minimal Complete and Verifiable Example that we can copy-paste, make it short, but still shows your issue and follows above recommendations
Important Note:
I'll bring a quote from This answer's comment of #MadProgrammer, because I used prototypeCellValue to make the rightList's width shorter:
I'd also be careful with prototypeCellValue, unless the value matches the expected length of your data, it could truncate your data when it's displayed, just need to be careful
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class QuestionTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
String[] foods = { "bacon", "wings", "ham", "beef", "more bacon" };
JFrame frame;
JPanel topPane, bottomPane, pane;
JList leftList, rightList;
JButton moveButton, clicMeButton;
JScrollPane scroll;
JLabel label;
frame = new JFrame("title");
topPane = new JPanel();
bottomPane = new JPanel();
pane = new JPanel();
leftList = new JList(foods);
rightList = new JList();
moveButton = new JButton("Move");
clicMeButton = new JButton("Click me!");
label = new JLabel("I'm unbreakable");
leftList.setVisibleRowCount(3);
rightList.setVisibleRowCount(3);
leftList.setPrototypeCellValue(String.format("%30s", ""));
rightList.setPrototypeCellValue(String.format("%30s", ""));
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
topPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
scroll = new JScrollPane(leftList);
topPane.add(scroll);
topPane.add(moveButton);
scroll = new JScrollPane(rightList);
topPane.add(scroll);
bottomPane.setLayout(new FlowLayout());
bottomPane.add(clicMeButton);
bottomPane.add(label);
pane.add(topPane);
pane.add(bottomPane);
frame.add(pane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Related
I am simply making a user interface and all i want it to do after the button is pressed is display thanks... I am pretty new to this but from what i see there are no errors? I have tried playing around with the set visible and to no avail...Any help is great thanks
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JList;
public class GuiApp1 {
public static void main(String args[]) {
String title = (args.length == 0 ? "CheckBox Sample" : args[0]);
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new GridLayout(0, 1));
Border border = BorderFactory.createTitledBorder("Pizza Toppings");
panel.setBorder(border);
JLabel label1 = new JLabel("Enter name below:");
panel.add(label1);
JTextField field = new JTextField(20);
panel.add(field);
JCheckBox check = new JCheckBox("Car0");
panel.add(check);
check = new JCheckBox("Car1");
panel.add(check);
check = new JCheckBox("Car2");
panel.add(check);
check = new JCheckBox("Car3");
panel.add(check);
check = new JCheckBox("Car4");
panel.add(check);
JButton button = new JButton("Submit");
final JPanel listPanel = new JPanel();
listPanel.setVisible(false);
JLabel listLbl = new JLabel("Vegetables:");
listPanel.add(listLbl);
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
listPanel.setVisible(!listPanel.isVisible());
panel.setVisible(!panel.isVisible());
}
});
Container contentPane = frame.getContentPane();
contentPane.add(panel, BorderLayout.CENTER);
contentPane.add(button, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.setResizable(true);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
The reason for the vegetables panel not appearing is simple: Xou never add ist to the contentPane.
For the code to function properly you need to add/remove the panels in the ActionListener of the button:
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
listPanel.setVisible(!listPanel.isVisible());
panel.setVisible(!panel.isVisible());
if (listPanel.isVisible()) {
contentPane.remove(panel); // Vegetables are visible, so remove the Cars
contentPane.add(listPanel, BorderLayout.CENTER); // And add the Vegetables
} else {
contentPane.remove(listPanel); // Vice versa
contentPane.add(panel, BorderLayout.CENTER);
}
}
});
Then, you need to move the ActionListener below the contentPane declaration and make it final.
Also you should consider putting the different checkboxes is different variables, so you can read the state of them. If you don't want to have so many variables hanging you could put them into an array.
JCheckBox[] checks = new JCheckbox[5];
checks[0] = new JCheckBox("Car0");
panel.add(checks[0]);
...
I'm a complete noobie with swing. I'm trying to set a few JPanels and TextAreas to show up but after spending 2 days reading the APIs and trying to add panels to frames and textareas to panels and nothing is showing up.. I'm utterly confused. If anyone could explain how is the best way to do this I would be very grateful
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(new FlowLayout()); // J FRAME
JPanel panel = new JPanel(); // first panel on the left
panel.setLayout(new BoxLayout(panel, 1));
// frame.getContentPane().setBackground(Color.red);
frame.add(panel);
JLabel surname = new JLabel();
JLabel initial = new JLabel();
JLabel ext = new JLabel();
surname.setOpaque(true);
initial.setOpaque(true);
ext.setOpaque(true);
frame.add(surname);
panel.add(initial);
panel.add(ext);
JTextArea table = new JTextArea();
table.setEditable(false);
panel.add(table);
table.setVisible(true);
You're adding stuff to the JFrame after it's already visible. If you do that, you need to revalidate your JFrame so it knows to redo its layout.
You could also just wait to show your JFrame until after you've added everything.
Edit: Here is an example program that shows what I'm talking about. Try running this, then take out the call to revalidate() to see the difference.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Test {
public static void main(String[] args) {
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton show = new JButton("Show");
show.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent showE) {
frame.add(new JLabel("Test"), BorderLayout.SOUTH);
frame.revalidate(); //tell the JFrame to redo its layout!
}
});
frame.add(show);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
You are adding an empty elements like:
JLabel surname = new JLabel();
Your elements is already added but have nothing to be display.
Try :
JLabel surname = new JLabel("UserName");
JLabel initial = new JLabel("Iinitial");
JLabel ext = new JLabel("Ext");
JTextArea table = new JTextArea(10, 5);
Working on adding a GUI to my simple craps simulation program.
Made a new JPanel and added a few JTextFields to it with a default text value. I get no error, and the code runs, but all I get is a blank window with nothing in it.
Here is the code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CrapsGUI extends JFrame
{
JPanel jp = new JPanel();
JLabel jl = new JLabel();
JTextField die1 = new JTextField("Die 1",30);
JTextField die2 = new JTextField("Die 2",30);
JTextField sum = new JTextField("Sum",30);
JTextField point = new JTextField("Point",30);
JTextField status = new JTextField("Status",30);
public CrapsGUI()
{
setTitle("Craps Simulator 2013");
setVisible(true);
setSize(400, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
jp.add(die1);
jp.add(die2);
jp.add(sum);
jp.add(point);
jp.add(status);
}
public static void main(String[] args)
{
Craps craps = new Craps();
CrapsGUI crapsGUI = new CrapsGUI();
}
}
Thanks in advance!
You haven't added the JPanel that contains the visible components.
add(jp);
Three things come to mind
Make sure you are starting your UI's from within the context of the Event Dispatching Thread. See Initial Threads for more details
Call setVisible only after you have finished creating your UI
It would also be helpful if you added something to you frame. Try using add(jp)
try this one:
public static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("Sample Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// first text box
JPanel textbox1Panel = new JPanel();
textbox1Panel.setLayout(new BoxLayout(textbox1Panel, 0));
textbox1Panel.setOpaque(true);
textbox1Panel.setBackground(new Color(100, 0, 131));
textbox1Panel.setPreferredSize(new Dimension(300, 300));
textbox1Panel.add(die1);
textbox1Panel.add(die2);
textbox1Panel.add(sum);
textbox1Panel.add(point);
// Set the menu bar and add the label to the content pane.
frame.getContentPane().add(textbox1Panel, BorderLayout.SOUTH);
// Display the window.
frame.pack();
frame.setVisible(true);
}
Could anyone point out where I am going wrong with this java swing gui code. I am trying to add two buttons to a JPanel and then add it into a frame after setting the size but it seems to not be responding to the setSize values passed to it
public Test() {
GridLayout layout = new GridLayout(1, 2);
//this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
This may not answer your immediate question...but...
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
// You're original code...
// Why are you using `BorderLayout.CENTER` on a `GridLayout`
this.add(new PaintSurface(), BorderLayout.CENTER);
You set the layout as a GridLayout, but you are using BorderLayout constraints to apply one of the components??
Also, make sure that there are not calls to Test#pack else where in your code, as this will override the values of setSize
UPDATED (from changes to question)
Remember, the default layout manager for JFrame is BorderLayout, so even though you're calling buttonPanel.setSize, it's likely that it's begin overridden by the layout manager anyway.
I would take a read through A Visual Guide to Layout Managers and Using Layout Managers to find a layout manager that best meets your requirements.
If you can't find a single one, consider using compound components with different layout managers to bring the layout closer to what you want to achieve.
Ok, I'll just give you a solution:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Cobie extends JFrame{
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
JPanel buttonPanel = new JPanel();
JPanel paintSurface = new JPanel();
public Cobie(){
setLayout(new GridLayout(2,1));
buttonPanel.setBackground(Color.RED);
paintSurface.setBackground(Color.BLUE);
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
add(buttonPanel);
add(paintSurface);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
Cobie c = new Cobie();
c.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
c.setSize(600,400); //Avoid using this method
c.setVisible(true);
}
});
}
}
According to your updated answer, you are not setting your layout on anything.
Anyway, if you use LayoutManager's (which you should), it is pointless to call setSize()/setBounds()/setLocation() since it will be overriden by the LayoutManager (that is actually its job).
And guessing that your Test class extends JFrame, by calling this.add(buttonPanel); this.add(new PaintSurface()); you are adding two components with the same constraint (BorderLayout.CENTER, since BorderLayout is the default LayoutManager of the content pane of the JFrame) to the content pane.
Consider reading the LayoutManager tutorial.
Just for information, although far from perfect, this shows something "working":
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test extends JFrame {
private JPanel buttonPanel;
public class PaintSurface extends JButton {
public PaintSurface() {
super("Paint surface dummy");
}
}
public Test() {
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
I designed an interface for the welcome screen with one JFrame included two JPanels (JPanel1 on right and JPanel2 on left). The buttons on the left is to switch the Panels in JPanel1. I want to press on a button to replace JPanel1 content with another JPanel but I don`t know how. Please help.
Here is a very simple example of something that should approximate your description. On the left, we have a hug button to toggle the content of the right panel. On the right, you have a panel with a given border and a label. When you press the button, the content on the right is swapped with the other panel.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestCardLayout2 {
protected void initUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel leftPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("Left panel");
leftPanel.add(label, BorderLayout.NORTH);
JButton button = new JButton("Toggle right panel");
leftPanel.add(button);
frame.add(leftPanel, BorderLayout.WEST);
final CardLayout cardLayout = new CardLayout();
final JPanel rightPanel = new JPanel(cardLayout);
rightPanel.setPreferredSize(new Dimension(200, 500));
JPanel rightPanel1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
rightPanel1.setBorder(BorderFactory.createLineBorder(Color.RED));
JPanel rightPanel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
rightPanel2.setBorder(BorderFactory.createLineBorder(Color.BLUE));
JLabel label1 = new JLabel("Right panel 1 with a red border");
JLabel label2 = new JLabel("Right panel 2 with a blue borer");
rightPanel1.add(label1);
rightPanel2.add(label2);
rightPanel.add(rightPanel1, "panel1");
rightPanel.add(rightPanel2, "panel2");
frame.add(rightPanel, BorderLayout.EAST);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.next(rightPanel);
}
});
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestCardLayout2().initUI();
}
});
}
}
An alternative to CardLayout would be JRootPane and its JRootPane.setContentPane() method. Here's an example:
final JPanel panel1 = ...;
final JPanel panel2 = ...;
boolean showingPanel1 = true;
final JRootPane rootPane = new JRootPane();
rootPane.setContentPane(panel1);
JButton switchButton = new JButton("Switch");
switchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (showingPanel1) {
rootPane.setContentPane(panel2);
} else {
rootPane.setContentPane(panel1);
}
showingPanel = !showingPanel;
}
});
Add the rootPane and switchButton components to your window, and then clicking switchButton will switch out the panels.
Here's a tutorial. You should mostly be concerned with JRootPane.setContentPane, the other stuff in the tutorial isn't relevant.
The best answer I found is that I will create one JFrame only and gonna make one big JPanel include two JPanels (JPanelLeft include the buttons and JPanelRight include what the button do) then I will copy the main JPanel for each JButton.
When I press on any button I will do (JFrame.getContentPane.removeAll) to remove the old JPanel then (JFrame.getContentPane.Add(NewJPanel).
This works for me and keep my design as I Want. Thanks for every body.