since some hours I am trying to create a JFrame whit following behavior:
I have a Title (with maybe an Image included) -This is centered at the top. -> Check
The rest of this JFrame should be filled with JPanel.
The first JPanel should be placed in the center on top. The second JPanel should be placed under the first and so on. When the first JPanel runs out of the screen, a second row needs to be created.
I dont care if they are reordered or not. Here is a drawing i prepared to show what I want:
Example - I need one of that behaviors
I have tried out so many combination of different Layouts.. But still can't find the right solution.
Here is my code, which is working fine besides the fact, that my panels are ordered from left to right instead of from top to down.. :(
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class myFrameClass extends JFrame {
myFrameClass() {
super();
setLayout(new BorderLayout());
GraphicsDevice[] gs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
GraphicsConfiguration[] gc = gs[0].getConfigurations();
setUndecorated(true);
setBackground(Color.WHITE);
setLocation(gc[0].getBounds().x, gc[0].getBounds().y);
setExtendedState(JFrame.MAXIMIZED_BOTH);
add(getHeader(), BorderLayout.NORTH);
add(getPanels());
setVisible(true);
}
private JPanel getPanels() {
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
int cnt = 6;
for (int i = 0; i < cnt; i++) {
p.add(getPanel());
}
return p;
}
private JPanel getPanel() {
JPanel p = new JPanel();
p.setBackground(Color.RED);
p.setPreferredSize(new Dimension(200, 200));
return p;
}
private JPanel getHeader() {
JPanel p = new JPanel();
p.add(new JLabel("Titel"));
return p;
}
public static void main(String args[]) {
new myFrameClass();
}
}
I also found Oracle VerticalFlowLayout but was not able to access it. Might it help me? In case - how to use it?
Otherwise.. How to use JFrame to archive that behavior?
Thank you
Related
Hello StackExchange community,
I'm at my wits end about this JSplitPane I'm trying to put into my frame, it is sitting on the right side of my frame instead of filling it up or atleast sitting on the left.
If anyone could help me with this issue I'd be very thankful.
See below an image of my problem and the code
The problem area is the pane with "tab1" and "tab2", the divider and the pane on the right side of that divider:
I've tried setting setAlignmentX(Component.LEFT_ALIGNMENT) on all the individual parts of the JSplitPane. I've also tried making a JPanel to hold it and aligning that. All to no avail.
Furthermore, existing information I've been able to find hasn't been relevant, mostly people discussing how to align the contents of the JSplitPane.
The code below is all that is needed to make this frame, if any of you need it to help me out feel free.
package test;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
public class FrameMaker {
public int x = 0;
private ArrayList<String> mpLabels;
private JFrame theFrame;
public void MakeFrame() {
theFrame = new JFrame("title");
theFrame.getContentPane().setLayout(new BoxLayout(theFrame.getContentPane(), BoxLayout.Y_AXIS));
mpLabels = new ArrayList<String>();
//label1
JPanel bgSwitches = new JPanel();
JLabel calcsLabel = new JLabel("top label, broadened with lines to exaggerate problem-------------------------------------------");
bgSwitches.add(calcsLabel);
//label2
JPanel topLevel = new JPanel();
JLabel textinfo = new JLabel("label below that");
topLevel.add(textinfo);
//splitpane tabs
mpLabels.add("tab1");
mpLabels.add("tab2");
String[] mpLabelsAr = new String[mpLabels.size()];
JList<String> posL = new JList<String>(mpLabels.toArray(mpLabels.toArray(mpLabelsAr)));
posL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//panel inside the right splitpane pane, this is needed for something later.
JPanel RPanel = new JPanel();
RPanel.setLayout(new BoxLayout(RPanel, BoxLayout.Y_AXIS));
JScrollPane scrollPos = new JScrollPane(posL);
JScrollPane scrollROI = new JScrollPane(RPanel);
JSplitPane posPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scrollPos,scrollROI);
posPanel.setOneTouchExpandable(false);
posPanel.setDividerLocation(75);
//label and textfield
JLabel msLabel = new JLabel("another label");
JTextField msField = new JTextField("textfield");
JPanel buttonPanel = new JPanel();
buttonPanel.add(msLabel);
buttonPanel.add(msField);
bgSwitches.setBackground(new Color(0,0,255));
theFrame.add(bgSwitches);
topLevel.setBackground(new Color(0,255,0));
theFrame.add(topLevel);
posPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
posPanel.setBackground(new Color(0,255,255));
theFrame.add(posPanel);
buttonPanel.setBackground(new Color(255,0,0));
theFrame.add(buttonPanel);
theFrame.pack();
theFrame.setVisible(true);
}
}
You need to align all of your other elements to the left as well.
bgSwitches.setAlignmentX(Component.LEFT_ALIGNMENT);
topLevel.setAlignmentX(Component.LEFT_ALIGNMENT);
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
You can also add posPanel.setResizeWeight(VALUE BETWEEN 0 AND 1); to specify what percent of the space the JSplitPane should occupy and it will resize with your window.
I'm having a very hard time with borders, I've looked through tutorials and examples and each seems to use a different style, I'm just trying to organise the content into separated borders. The content for the bottom panal isn't finished yet but I'm just trying to get it to work as is before adding more.
The compiler says there are problems on two lines java.lang.NullPointerException:
package question2;
import java.awt.Color;
import java.awt.Component;
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.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
/**
* #author Matt Headley
This frame shows a data set and its statistics.
*/
public class ComputerStoreGUI extends JFrame
{
private JCheckBox item1;
private JCheckBox item2;
private JCheckBox item3;
private JCheckBox item4;
private JCheckBox item5;
private TitledBorder border;
private TitledBorder border2;
private static JPanel content;
private static JPanel top;
private static JPanel bottom;
private JTextField parts;
public ComputerStoreGUI()
{
JCheckBox item1 = new JCheckBox("Install Hard Drive - $25.00");
JCheckBox item2 = new JCheckBox("Install RAM - $15.00");
JCheckBox item3 = new JCheckBox("Remove Virus - $50.00");
JCheckBox item4 = new JCheckBox("Format Hard Drive - $80.00");
JCheckBox item5 = new JCheckBox("Quote Hourly Labour - $10.00");
item1.setHorizontalAlignment(JCheckBox.LEFT);
item2.setHorizontalAlignment(JCheckBox.LEFT);
item3.setHorizontalAlignment(JCheckBox.LEFT);
item4.setHorizontalAlignment(JCheckBox.LEFT);
item5.setHorizontalAlignment(JCheckBox.LEFT);
JTextField cost = new JTextField(10);
top = new JPanel(new FlowLayout(FlowLayout.LEFT));
top.add(item1);
top.add(item2);
top.add(item3);
top.add(item4);
top.add(item5);
bottom.add(cost); //here ????????
cost.setHorizontalAlignment(JTextField.CENTER);
}
public static void main(String[] args)
{
JFrame frame = new ComputerStoreGUI(); // and here ???????
content = new JPanel();
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
top = new JPanel();
top.setBorder(BorderFactory.createTitledBorder("Standard Services"));
bottom = new JPanel();
bottom.setBorder(BorderFactory.createTitledBorder("Hourly Service"));
frame.setSize(250, 400);
frame.setTitle("LU Computer Store");
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content.add(top);
content.add(bottom);
frame.setVisible(true);
}
}
the end goal is to look something like this:
First, I dont see a reson to extend JFrame in your example. So without inheritance you can use composition like:
JFrmae frame = new JFrame();
Read more: Why do we need to extend JFrame in a swing application?
The compiler says there are problems on two lines
java.lang.NullPointerException:
Reason is, you have declared the JPanel bottom but without initializing you are trying to use it, from this line: bottom.add(cost);
Do something like:
bottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
bottom.add(cost);
EDIT:
comment: It runs now, but the panels are tiny
Because you need to set layout for the parent JPanel, you can use BoxLayout, to add child panels one below another, like below:
content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
In case if you want to add space between those two child panels, use as below:
content.add(top);
content.add(Box.createRigidArea(new Dimension(0,10)));
content.add(bottom);
I'm trying to implement a feature that (in my test project) once a button is pressed, it adds a random number to my JPanel. (I use the layouts I have because in my real program, I have more items inside and it displays correctly). But I need my program to recognize when the scrollbar is visible (which I implemented that, but it's a little delay. What I mean by delay is I push the button to add a number, if the scrollbar becomes visible nothing happens. But then the next time I press the button it shifts over like I want). The other problem I have (the one I'm focused on now) is that when I dynamically change the size of the JPanel, if the scrollbar is visible, I have it set to change the width to my width - the width of the scrollbar. But It seems like when the scrollbar is visible, the newly inputted number moves over twice the scrollbar width instead of just once. I've been at this part of my program for over a day and can't figure it out. I'll add my full code and some screenshots.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Main {
JFrame frame;
JPanel topPanel;
JPanel memoryPanel;
JScrollPane sPane;
JButton button;
ArrayList<Integer> list = new ArrayList<>();
boolean isVScrollVisible = false;
int scrollBarSize = 0;
public class MyChangeListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
isVScrollVisible = (sPane.getVerticalScrollBar().isVisible());
}
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Random random = new Random();
int r = random.nextInt(10);
list.add(r);
int n;
if (isVScrollVisible) {
n = scrollBarSize;
} else {
n = 0;
}
JPanel nextPanel = new JPanel();
nextPanel.setName("" + r);
nextPanel.setForeground(Color.BLACK);
nextPanel.setPreferredSize(new Dimension(200 - n, 55));
nextPanel.setMinimumSize(new Dimension(200 - n, 55));
nextPanel.setMaximumSize(new Dimension(200 - n, 55));
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BorderLayout());
JLabel label = new JLabel();
label.setText("" + r);
label.setPreferredSize(new Dimension(200 - n, 55));
label.setMinimumSize(new Dimension(200 - n, 55));
label.setMaximumSize(new Dimension(200 - n, 55));
label.setHorizontalAlignment(JLabel.RIGHT);
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 17));
label.setFont(new Font("Sans-Serif", Font.BOLD, 20));
labelPanel.add(label);
nextPanel.add(labelPanel, BorderLayout.LINE_START);
for (int i = 0; i < memoryPanel.getComponents().length; i++) {
memoryPanel.getComponent(i).setPreferredSize(new Dimension(200 - n, 55));
memoryPanel.getComponent(i).revalidate();
memoryPanel.getComponent(i).repaint();
}
memoryPanel.add(nextPanel, 0);
memoryPanel.revalidate();
memoryPanel.repaint();
sPane.revalidate();
sPane.repaint();
}
}
public Main() {
frame = new JFrame();
topPanel = new JPanel();
memoryPanel = new JPanel();
memoryPanel.setLayout(new BoxLayout(memoryPanel, BoxLayout.Y_AXIS));
sPane = new JScrollPane(memoryPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sPane.setPreferredSize(new Dimension(200, 300));
sPane.getViewport().addChangeListener(new MyChangeListener());
scrollBarSize = ((Integer)UIManager.get("ScrollBar.width")) + 1;
button = new JButton("Add Random Number");
button.addActionListener(new ButtonListener());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
topPanel.add(button);
frame.add(topPanel, BorderLayout.PAGE_START);
frame.add(sPane, BorderLayout.CENTER);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
I need them to look exactly the same. Before I had the code I have now, the scrollbar would appear over the numbers which looked ugly. And the reason I have the frame resizable false is because In my real program I hard coded all the sizes, which in the future I will calculate the correct sizes based on the size of the frame, so right now setting resizable to true is out of the question. Any suggestions on what to do?
This is what I'm trying to accompolish.
Get rid of all the logic that sets the preferred/minimum/maximum sizes. Each component knows what its size should be. Each layout manager will in turn know what the preferred size of the panel should be. Let the layout manager use the information to do its job.
The basic logic for dynamically adding components is:
panel.add(...);
panel.revalidate();
panel.repaint();
Then the scrollbars will appear automatically when required. There is no need for listeners or anything.
Edit:
The reason I set all the sizes is because If I take them out then everything appears centered
Learn how to use layout managers properly and effectively.
For example when using a BoxLayout you can control the alignment of components by using:
component.setAlignmentX(JLabel.RIGHT_ALIGNMENT);
and the component will be aligned to the right edge of the space available to the component.
When using a JLabel you may also need to set a property on the JLabel to align the text to the right edge of the label. Read the JLabel API for the appropriate method.
I want to put space between buttons:
I want to put the buttons in the center, one below the other with distance between them, I apologize if my code is messy, I want to do something more complicated, it is only a prototype, plus you do not know so well Java GUI so accepted criticism
Class first:
import javax.swing.*;
public class first {
public static void main(String[] args) {
second ob = new second();
ob.setLocation(500, 100);
ob.setSize(500, 500);
ob.setVisible(true);
ob.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Class second:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.util.Formatter;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.Position;
import java.util.*;
public class second extends JFrame {
int i;
private JPanel pan1;
private JPanel pan2;
private JScrollPane scroll;
private JTextArea tx;
private JButton[] buton = new JButton[50];
private Box box = new Box(BoxLayout.Y_AXIS);
second() {
pan1 = new JPanel();
pan1.setBackground(Color.GREEN);
pan1.setLocation(0, 0);
pan1.setPreferredSize(new Dimension(500, 100));
add(pan1, BorderLayout.NORTH);
for (int i = 0; i < 50; i++) {
buton[i]=new JButton("Button "+i);
box.add(buton[i]);
}
JScrollPane sp = new JScrollPane(box);
Dimension d = new Dimension(box.getComponent(0).getPreferredSize());
sp.getVerticalScrollBar().setUnitIncrement(d.height);
d.height *= 10; // Show at least 10 buttons
sp.getViewport().setPreferredSize(d);
add(sp);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
one below the other with distance between them
Read the section from the Swing tutorial on How to Use BoxLayout. You can add a verticalStrut(...) between each button You use the Box.CreateVerticalStrut(...) method for this.
Another approach might be to use a GridLayout. You can specify a vertical gap in the grid when you create the layout. Note: using this approach all buttons will be the same size and will fill the space available, in which case you may need to nest the panel with the GridLayout in another panel so the buttons are displayed at a reasonable width.
Class names SHOULD start with an upper case character. Look at all the classes in the JDK API. Note how they all start with an upper case character.
Been having a hard time adding JPanels to JFrame. Am pretty much new on java, always used C++
I need to do 4 Panels inside one Frame.
Here is my Code, just started today..
package project2;
import javax.swing.JOptionPane;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.Container;
import java.awt.Dimension;
public class GUI extends JFrame
{
private JPanel Checks; //Panel to Hold Checks
private JPanel Transactions;
private JPanel History;
private JPanel Graphics;
private JLabel CLabel;
public GUI()
{
super ( "UTB Check-In");
JPanel Checks = new JPanel(); //set up panel
CLabel = new JLabel("Label with text");
Checks.setBackground(Color.red);
Checks.setLayout( new BoxLayout(Checks,BoxLayout.LINE_AXIS));
add(Checks);
// JPanel Transactions = new JPanel();
// Transactions.setToolTipText("Electronic Transactions");
//Transactions.setBackground(Color.blue);
// add(Transactions);
}
}
I was trying to put Transaction and Checks one side from the other with different colors,in this case blue and red it doesnt stay in the middle it those one or the other.
One of my Colleagues told me that the BoxLayout(or any layout) needed to be implemented with the size..something to that extend. am not really sure I been reading
http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html
But I still do not get it completely. If somebody can help me out
thanks!
Your code fail cause you are adding directly to the JFrame which have by default BorderLayout. You are setting BoxLayout to the wrong panel.
You have to setLayout() to the top component(jframe) that you are adding or as i prefer adding to a jpanel rather than directly to the jframe to acomplish what you want to do.
Example:
public GUI()
{
super ( "UTB Check-In");
JPanel parent = new JPanel();
parent.setLayout(new BoxLayout(parent,BoxLayout.LINE_AXIS));
add(parent);
JPanel Checks = new JPanel(); //set up panel
CLabel = new JLabel("Label with text");
Checks.setBackground(Color.red);
parent.add(Checks);
JPanel Transactions = new JPanel();
Transactions.setToolTipText("Electronic Transactions");
Transactions.setBackground(Color.blue);
parent.add(Transactions);
}
By the way, in Java variables starts with lowerCase as a code convention.