Java layout with frames and panels - java

I'm building my first Java swing GUI, but I cannot manage to have the layout as I wanted.
Can you help me to understand how the layout should be set to have the desired result (see image below)?
This is what I get (wrong):
and if I resize it manually I get the desired result:
Here is my code:
public class MainClass implements Runnable {
private JButton load = new JButton("Load..");
private JButton save = new JButton("Save..");
private JButton clear = new JButton("Clear");
private JLabel displayFile = new JLabel();
List<String> lines;
JFrame frame = new JFrame("SimpleDrawing");
public static void main(String[] args) {
MainClass maincl = new MainClass();
SwingUtilities.invokeLater(maincl);
}
#Override
public void run() {
DrawingArea area = new DrawingArea();
frame.setLayout(new FlowLayout());
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
//buttonPane.add(Box.createHorizontalGlue());
buttonPane.add(load);
//buttonPane.add(Box.createRigidArea(new Dimension(5,0)));
buttonPane.add(save);
//buttonPane.add(Box.createRigidArea(new Dimension(5,0)));
buttonPane.add(clear);
buttonPane.add(displayFile);
frame.add(buttonPane, BorderLayout.PAGE_START);
frame.add(area, BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

Your Frame has the FlowLayout.
frame.setLayout(new FlowLayout());
Give it a BorderLayout.
frame.setLayout(new BorderLayout());
Layout- Informations:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Related

Java how to bottom align button and filter label to right

Hi I am trying to make a GUI using Javax to look something like this.
But currently it looks like this
This is my code
class Intro extends JFrame implements ActionListener
{
JFrame frame = new JFrame();
JButton ok;
JLabel background;
JLabel demo;
public Intro()
{
frame.setTitle("Let us start");
frame.setSize(600,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new JLabel(new ImageIcon("welcome.gif")));
frame.setLayout(new FlowLayout());
background = new JLabel();
frame.add(background);
frame.setSize(500,400);
ok = new JButton("OK");
demo = new JLabel("CSIT 121 Demo System", SwingConstants.RIGHT);
frame.add(demo);
ok.setHorizontalTextPosition(JButton.CENTER);
ok.setVerticalTextPosition(JButton.BOTTOM);
frame.add(ok);
}
}
What do i need to modify?
You should use another layout. Here is the correct example:
public class Intro extends JFrame {
JFrame frame = new JFrame();
JButton ok;
JLabel background;
JLabel demo;
public Intro() {
frame.setTitle("Let us start");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel contentPane = new JLabel(new ImageIcon("welcome.gif"));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
frame.setContentPane(contentPane);
frame.setLayout(new BorderLayout());
background = new JLabel();
frame.add(background); // why you need it??? it has no visual effect here
frame.setSize(500, 400);
ok = new JButton("OK");
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(ok);
frame.add(buttonPanel, BorderLayout.PAGE_END);
demo = new JLabel("CSIT 121 Demo System"); // probably you need to change foreground of label to fit your background image
frame.add(demo, BorderLayout.LINE_END);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Intro::new);
}
}

How to have a JButton that moves as I scroll on the frame?

I have a Panel which I have made scrollable in my frame.
What I need is to add a button that stays fixed in the lower right corner even when I scroll.
I'm new to Java Swing so would appreciate all and any help that I can get.
mainPanel = new SimulationPanel(); //class SimulationPanel extends JPanel
//making mainPanel scrollable
mainPanel.setPreferredSize(new Dimension(((int)(WIDTH*1.2)), HEIGHT));
JScrollPane scrollPane = new JScrollPane(mainPanel);
scrollPane.setViewportView(mainPanel);
// Settings for JFrame
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("Warehouse Simulator");
frame.setContentPane(scrollPane);
frame.setSize(screenSize.width, screenSize.height);
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
I would use nested panels with the outer one be with BorderLayout. Then one with FlowLayout and align FlowLayout.RIGHT and the button inside it.
public class Example extends JFrame {
public Example() {
super("");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTextArea textArea = new JTextArea(10000, 0);
JScrollPane scrollPane = new JScrollPane(textArea);
add(scrollPane, BorderLayout.CENTER);
JButton button = new JButton("button");
JPanel panelWithButton = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panelWithButton.add(button);
add(panelWithButton, BorderLayout.PAGE_END);
setLocationByPlatform(true);
pack();
setSize(600, 600);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Example().setVisible(true);
});
}
}
Result:
I would go for a BoxLayout. Add another panel (metaPanel) in which your first put your scrollingPanel, and then you add a button. Instead of usgin scrollingPanel as contentPane, you use metaPanel. Example (the example works, but you need to modify it to make the interface look nice):
JPanel mainPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(mainPanel);
scrollPane.setViewportView(mainPanel);
JPanel metaPanel = new JPanel();
BoxLayout boxlayout = new BoxLayout(metaPanel, BoxLayout.Y_AXIS);
metaPanel.setLayout(boxlayout);
metaPanel.add(scrollPane);
metaPanel.add(new JButton("button"));
// Settings for JFrame
frame = new JFrame("Warehouse Simulator");
frame.setContentPane(metaPanel); // Put metaPanel here
frame.setSize(500, 300);
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);

Content is being add horizontally to JScrollPane

im starting to work with java Swing and i was trying to make a system to show something like a Map :
But when i try to add another entry to the JSCrollPane it's being added horizontally intead of vertically, i have tried everything i don't what i mithgt be doing wrong but i can't manage do fix it.
Here i create the Frame :
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel panel = new JPanel();
final JPanel content = new JPanel();
new DataEntry("", 0).create(content);
final JScrollPane scrollPane = new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setWheelScrollingEnabled(true);
panel.add(scrollPane);
scrollPane.setMinimumSize(new Dimension(400, 60));
final JButton add = new JButton("Add");
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new DataEntry("", 0).create(content);
}
});
panel.add(add);
frame.setContentPane(panel);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.pack();
frame.setVisible(true);
And this is how i create the Entry :
public JPanel create(final JPanel content) {
final JPanel panel = new JPanel();
final JPanel fields = new JPanel();
fields.add(new JLabel("Variable"));
fields.add(variable);
fields.add(new JLabel("Row"));
fields.add(row);
panel.add(fields);
JButton remove = new JButton("Remove");
remove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
content.remove(panel);
content.revalidate();
}
});
panel.add(remove);
content.add(panel, BorderLayout.CENTER);
content.revalidate();
return panel;
}
At the start i was wondering why it wasn't displaying any new Entry, then i tried changing HORIZONTAL_SCROLLBAR_NEVER > HORIZONTAL_SCROLLBAR_AS_NEEDED and then i realized that the variables were being add horizontally.
Here is a gif to see what's going on (Couldn't manage to take a proper photo) : GIF

cannot add dynamic jtextfields and save their values

In previos my questions I asked similar questions to this. But in my previous projects I used GUI builder, so now I would like to add JTextField to the Panel dynamically without Builder. I don't why but for some reason I cannot execute this code:
public class Reference {
JFrame frame = new JFrame();
JPanel MainPanel = new JPanel();
MainPanel main = new MainPanel();
JPanel SubPanel = new JPanel();
JButton addButton = new JButton();
JButton saveButton = new JButton();
private List<JTextField> listTf = new ArrayList<JTextField>();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Reference();
}
public Reference() {
frame.add(main);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(addButton, BorderLayout.EAST);
frame.add(saveButton, BorderLayout.WEST);
frame.pack();
frame.setSize(500, 300);
frame.setVisible(true);
main.setLayout(new BorderLayout());
main.setBackground(Color.green);
main.add(SubPanel);
SubPanel.setBackground(Color.yellow);
addButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
main.add(new SubPanel());
main.revalidate();
}
});
saveButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
for (int i = 0; i < main.getComponentCount();) {
SubPanel panel = (SubPanel)main.getComponent(i);
JTextField firstName = panel.getFirstName();
String text = firstName.getText();
System.out.println( text );
}}
});
}
private class SubPanel extends JPanel {
JTextField firstName = new JTextField(15);
public SubPanel() {
this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
this.add(firstName);
listTf.add(firstName);
}
public JTextField getFirstName()
{
return firstName;
}
}
public class MainPanel extends JPanel
{
List<SubPanel> subPanels = new ArrayList<SubPanel>();
public MainPanel()
{
}
public void addSubPanel()
{
SubPanel panel = new SubPanel();
add(panel);
subPanels.add(panel);
}
public SubPanel getSubPanel(int index)
{
return subPanels.get(index);
}
}
}
And by saveButton trying to get value of JTextField, but without success. In output I can see just JFrame with 2 Buttons, but ActionListener of addButton and saveButton is not active. I cannot understand where is wrong.
Any help would be much appreciated.
In Swing, the order you do some things is very important, for example...
frame.add(main);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(addButton, BorderLayout.EAST);
frame.add(saveButton, BorderLayout.WEST);
frame.pack();
frame.setSize(500, 300);
frame.setVisible(true);
You add main to your frame
You set the frames layout (!?)
You add your buttons
You pack the frame
You set it's size (!?)
You make it visible
The problem here is step #2. If, instead, we simply remove step #2 (step #4 and #5 aren't great either), you will find that your window now contains main...
frame.add(main);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(addButton, BorderLayout.EAST);
frame.add(saveButton, BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
This...
for (int i = 0; i < main.getComponentCount();) {
SubPanel panel = (SubPanel) main.getComponent(i);
a bad idea of three reasons;
Your loop will never advance (i will always be 0)
You are blindly casting the contents of main without actually knowing what's on it
MainPanel already has a List of SubPanels...
You need to make sure that you are adding SubPanels via the addSubPanel method (and this should probably return an instance of the SubPanel) and provide a means by which you can access this List, maybe via a getter of some sort. Although, I'd be more interested in their values (ie the text field text) rather then the SubPanel itself ;)

How to resize a JPanel

I am trying to resize the JPanels but there is a space under it . Here is a link to show :
And this is the code :
import java.awt.*;
import javax.swing.*;
public class Ex1 extends JFrame{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();``
private JButton buton = new JButton ("Trimite");
public Ex1(){
JPanel panel = new JPanel (new BorderLayout(2,2));
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.setPreferredSize(new Dimension(350,100));
panel2.setPreferredSize(new Dimension(350,25));
panel1.add(label1, BorderLayout.NORTH);
panel1.add(textarea, BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
setLayout(new GridLayout(2,1,1,1));
panel.add(panel1, BorderLayout.NORTH);
panel.add(panel2, BorderLayout.CENTER);
add(panel);
}
public static void main(String[] args) {
JFrame frame = new Ex1();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
You are setting a layout for a frame to GridLayout in which all components are given equal size. You have two rows, add(panel) adds the panel to the first row of the grid. The second row is left empty. See How to Use GridLayout.
Comment out setLayout(new GridLayout(2,1,1,1)); and the extra space should go away. When you comment this line the layout of frame's content pane will be BorderLayout. The default layout of the JFrame is BorderLayout. So add(panel); will add the panel to the center of the frame's content pane. As a result the panel should occupy all the available space.
As a side note, avoid setPreferredSize(), usually it is not necessary, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing for details.
You can specify the number of rows and columns for a text area and wrap it in the scroll pane, ie:
textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane(textArea);
For more details see How to Use Text Areas
EDIT: example of getPreferredSize()
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
public class Ex1 extends JPanel{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();
private JButton buton = new JButton ("Trimite");
public Ex1() {
setLayout(new BorderLayout());
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.add(label1, BorderLayout.NORTH);
panel1.add(new JScrollPane(textarea), BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
add(panel1, BorderLayout.CENTER);
add(panel2, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(350, 300);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
Ex1 panel = new Ex1();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
You need to resize the JFrame not the JPanel. Try:
this.setPreferredSize(new Dimension(350, 25);// in Ex1
Or in your main method:
frame.setPreferredSize(new Dimension(350, 25);

Categories

Resources