Java Swing - Buttons on a new line - java

enter code hereI have a UI with a toolbar to apply different filters on an image and the image is displayed on the right side (the toolbar is on the left side) I am adding new buttons but the toolbar is now really long and i want to give a limit so once it is reaching 1/5 of the total frame, I want to display the buttons on a new line.
public class Toolbar extends JPanel {
private JButton filterOne;
private JButton filterTwo;
private JButton filterThree;
private JButton loadImage;
private JLabel picture;
Toolbar(){
filterOne = new JButton("filterOne");
filterTwo = new JButton("filterTwo");
filterThree = new JButton("filterThree");
loadImage = new JButton("loadImage");
picture = new JLabel();
setLayout(new FlowLayout());
add(loadImage);
loadImage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ImageIcon pic = new ImageIcon("ImageOne.png");
picture.setIcon(pic);
}
});
add(filterOne);
add(filterTwo);
add(filterThree);
add(picture);
}
}
public class MainFrame extends JFrame {
private JTextArea textArea;
private Toolbar toolbar;
private ImagePannel imagePannel;
MainFrame() {
// Generating a new
setLayout(new BorderLayout());
// Generating a new toolbar that contains all the buttons to generate new images.
toolbar = new Toolbar();
imagePannel = new ImagePannel();
add(imagePannel,BorderLayout.CENTER);
// Position of the toolbar within the upper side of the pannel.
add(toolbar, BorderLayout.WEST);
//This is the name of the window
JFrame frame = new JFrame("My view");
//Initialize the size of the window
setSize(1200, 800);
//Makes the window close when we are crossing the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Makes the window visible
setVisible(true);
}
}

...so once it is reaching 1/5 of the total frame, I want to display the buttons on a new line.
Don't use setLayout(new FlowLayout()); since this is not a "smart" layout, one you can control easily. Instead use a different layout, perhaps GridLayout(0, 5) -- one with a variable number of rows and with 5 columns.

Related

How to place JTextArea object at a certain place on a JPanel?

I am trying to implement a JAVA GUI app, but I am facing a problem that I could not find the solution anywhere about how to move the JTextArea to a certain place on the panel. I took a picture of the software.
I have tried many ways to make the white JTextArea object placed below the big JTextArea object on the right panel. Does anyone have any idea about this? Like how to move the JTextArea object around the others, and how to make the JButton/JTextArea objects stay in the fixed place?
public class menu extends JFrame {
private JButton generate, sort;
private final JTextArea TEXT_AREA_EAST = new JTextArea(30,40);
private final JTextArea TEXT_AREA_WEST = new JTextArea(30,40);
private final JTextArea TEXT_AREA_EAST_BELOW = new JTextArea(5,30);
private void display() {
setTitle ("Sorting Algorithm Runtime Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,300);
setLocationRelativeTo(null);
setLayout(new GridLayout(5,2,5,5));
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.white);
contentPane.setBorder(
BorderFactory.createEmptyBorder(horizontal, horizontal, horizontal, horizontal));
contentPane.setLayout(new BorderLayout(horizontal, vertical));
ButtonGroup bg = new ButtonGroup();
rightPanel = new JPanel();
rightPanel.setOpaque(true);
rightPanel.setBackground(Color.yellow);
border = BorderFactory.createTitledBorder("Sorted List");
border.setTitleJustification(TitledBorder.CENTER);
rightPanel.setBorder(border);
sort = new JButton("Sort");
rightPanel.add(sort, JPanel.TOP_ALIGNMENT);
rightPanel.add(TEXT_AREA_EAST, BorderLayout.EAST);
rightPanel.add(TEXT_AREA_EAST_BELOW, BorderLayout.SOUTH);
TEXT_AREA_EAST.setBackground(Color.CYAN);
TEXT_AREA_EAST.setEditable(false);
This is how the app look like

JLabel won't display image in class

I'm currently trying to create a GUI in which two images of coins are displayed next to each other in the center of a borderlayout. I have one class (Images) in which I attempt to use JLabel to display the Icons and another class which handles the GUI Frame (GameGUI). However despite my best efforts the labels don't display the images. I've looked through countless tutorials and can't find anything to fix this. The relative paths are correct, how can I fix this?
Images Class
public class Images extends JLabel{
private JLabel heads, tails;
public Images() {
heads = new JLabel(new ImageIcon("img/heads.png"));
tails = new JLabel(new ImageIcon("img/tails.png"));
add(heads);
add(tails);
}
}
GameGUI Class
public class GameGUI extends JFrame{
public GameGUI() {
super("");
setLayout(new BorderLayout(10,10));
Menu menu = new Menu();
ToolBar toolBar = new ToolBar();
Images images = new Images();
setJMenuBar(menu);
add(BorderLayout.NORTH, toolBar);
add(BorderLayout.CENTER, images);
setSize(1000, 500);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Problem:
public class Images extends JLabel{
private JLabel heads, tails;
public Images() {
heads = new JLabel(new ImageIcon("img/heads.png"));
tails = new JLabel(new ImageIcon("img/tails.png"));
add(heads);
add(tails);
}
}
JLabels use a null layout, meaning your internal JLabel components will have a size of 0, 0, and the Images JLabel itself will have a preferred size of the same, and nothing will show, and so you never want to add a JLabel to a JLabel. Don't have images extend JLabel, but rather JPanel, and give it a decent layout, perhaps GridLayout.
e.g.,
public class ImagePanel extends JPanel {
private JLabel headsLabel = new JLabel();
private JLabel tailsLabel = new JLabel();
public ImagePanel(Icon headsIcon, Icon tailsIcon) {
headsLabel.setIcon(headsIcon);
tailsLabel.setIcon(tailsIcon);
setLayout(new GridLayout(1, 0);
add(headsLabel);
add(tailsLabel);
}
}
Again, I would recommend getting the images as resources, not as Files using ImageIO read, something like
Image headImage = ImageIO.read(getClass().getResource(resourcePath));
Icon headIcon = new ImageIcon(headImage);
the resource path will be critical and will depend on where the images are relative to your class files.

Java GUI - How to center a single button

I'm very new to java (I'm used to python).
NOTE: I do want the position to stay in the center even when the gui is resized.
I was wondering how I can center a single button? At the moment, the button is at the top of the gui.
public class main_gui extends JFrame{
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
// Take out the border around the text
start_button.setFocusable(false);
start_panel.add(start_button);
}
}
Here is what is currently looks like, I just want this button down a bit, to the center.
There is no need for the panel. Just add the button directly to the frame.
The easiest way is to use a GridBagLayout:
frame.setLayout( new GridBagLayout() );
frame.add(startButton, new GridBagConstraints());
By default the component will be centered horizontally and vertically within the GridBagLayout.
A quick solution would be to set the vertical gap between components of your FlowLayout to half the size of your JFrame:
public class MainGUI {
static java.awt.Dimension bd;
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Button to initialize everything
JButton start_button = new JButton("Start");
bd = start_button.getPreferredSize();
// Take out the border around the text
start_button.setFocusable(false);
// Panel to hold our buttons
java.awt.Dimension d = start_frame.getSize();
JPanel start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
start_panel.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent evt) {
JPanel c = (JPanel) evt.getSource();
c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
}
});
start_panel.add(start_button);
start_frame.add(start_panel);
start_frame.setVisible(true);
}
}
When the size of your JFrame is changed, the ComponentAdapter recalculates the new height and places the button to the new center.
In order to place the button to the vertical center, we calculate the height of your button and subtract its half from the vertical gap.
The horizontal center is automatically applied by the layout.
Your class should not extend JFrame if you instantiate another JFrame inside it and use it.
Class names should be nouns, in mixed case with the first letter of each internal word capitalized.
It is recommended to make your JFrame visible after you have added all widgets to it.
In order to use the SwingUtilities invoker and make your application code cleaner, let your class extend JFrame, write a constructor and call it this way:
public class MainGUIJFrame extends JFrame {
public MainGUIJFrame() {
initComponents();
}
private void initComponents() {
setTitle("P.D");
setSize(1200, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start_button = new JButton("Start");
bd = start_button.getPreferredSize();
// Take out the border around the text
start_button.setFocusable(false);
java.awt.Dimension d = getSize();
start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
start_panel.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent evt) {
JPanel c = (JPanel) evt.getSource();
c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
}
});
start_panel.add(start_button);
add(start_panel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MainGUIJFrame().setVisible(true);
}
});
}
private JButton start_button;
private JPanel start_panel;
private java.awt.Dimension bd;
}
You keep main simple and small this way, and bd does not have to be static anymore.
You can use a layout manager like BorderLayout if you want to put the button in the center so that it occupies the whole space in the frame. So, your code will look something like this:
public class main_gui extends JFrame{
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(new BorderLayout());
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
// Take out the border around the text
start_button.setFocusable(false);
start_panel.add(start_button, BorderLayout.CENTER);
}
}
You may go without using a layout manager. It's a bad practice but it should work. This code will put a small button in the center of the frame:
public class MainGUI {
public static void main(String[] args) {
JFrame start_frame = new JFrame("P.D");
int width = 1200;
int height = 800;
start_frame.setSize(width, height);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(null);
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
buttonWidth = 80;
buttonHeight = 20;
start_button.setBounds(new Rectangle((width - buttonWidth)/2, (height - buttonHeight)/2, buttonWidth, buttonHeight));
start_button.setSize(new Dimension(buttonWidth, buttonHeight));
start_button.setFocusable(false);
start_panel.add(start_button);
}
}
The best way to do it is to use a Layout of your choice and try to make it work using that.
However, if you are sure your window won't be getting resized, or you're happy to deal with such events yourself, you could attempt working without a layout and position the button manually, e.g.:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.Dimension;
public class main_gui {
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
int FrameWidth = 1200, FrameHeight = 800;
start_frame.setSize(FrameWidth, FrameHeight);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(null); // Now working without a layout manager
// i.e, can position things manually.
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
start_button.setFocusable(false); // Take out the border around the text
Dimension size = start_button.getPreferredSize();
start_button.setBounds( FrameWidth/2 - size.width/2,
FrameHeight/2 - size.height/2,
size.width, size.height);
start_panel.add(start_button);
// Display the Layout after all components have been added.
// (adding components after the frame has been set to visible
// may result in components not showing up reliably!)
start_frame.setVisible(true);
}
}

Resize JButtons in a BoxLayout

I'm trying to make a simple menu for my game. I have 4 buttons in the center and I want to make them a little bit bigger and center them.
The last part worked but I can't seem to call any of my JButtons and do a .setSize / .setPreferedSize(new Dimension()) on it.
public class mainMenu extends JFrame {
private JButton start, highscore, help, stoppen;
public mainMenu() {
super("Master Mind");
maakComponenten();
maakLayout();
toonFrame();
}
private void maakComponenten() {
start = new JButton("Start");
start.setBackground(Color.gray);
highscore = new JButton("Higscores");
help = new JButton("Help");
stoppen = new JButton("Stoppen");
}
private void maakLayout() {
JPanel hoofdmenu = new JPanel();
hoofdmenu.setLayout(new BoxLayout(hoofdmenu, BoxLayout.Y_AXIS ));
hoofdmenu.add(start);
start.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(highscore);
highscore.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(help);
help.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(stoppen);
stoppen.setAlignmentX(CENTER_ALIGNMENT);
super.add(hoofdmenu);
}
private void toonFrame() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
setSize(500,500);
}
public static void main(String[] args) {
new mainMenu();
}
}
As an example, to change the size of the "Start" button,
change :
start1 = new JButton("Start");
to
start1 = new JButton("Start") {
{
setSize(150, 75);
setMaximumSize(getSize());
}
};
The problem is that JFrames use BorderLayout by default, which means that your JPanel will naturally fill the space.
Before adding your JPanel, call the following code to change the JFrame's layout to null and use the JPanel's settings instead.
this.setLayout(null);
JPanel hoofdmenu = new JPanel();
hoofdmenu.setBounds(0,0, 400, 100);
Alternatively, you could set the maximum size of the JButtons
Dimension maxSize = new Dimension(100, 100);
start.setMaximumSize(maxSize);
highscore.setMaximumSize(maxSize);
help.setMaximumSize(maxSize);
stoppen.setMaximumSize(maxSize);
Here's another example following behind the previous two - I'm making a soundboard program, and this is actually a sample from it - The JPanel actually is needed, agreeing to the second post.
JFrame frame = new JFrame();
JPanel menuPanel = new JPanel();
JButton Button1 = new JButton("<BUTTON NAME 1>");
Button1.setSize(80, 30);
Button1.setLocation(4, 4);
JButton Button2 = new JButton("<BUTTON NAME 2>");
Button2.setSize(80, 30);
Button2.setLocation(90, 4);
Ah, and another thing - You created the buttons in a different block from the second piece of code. Doing that causes the other blocks to not see it. You need to declare them outside the block so all the blocks can see them.

Centering JButton in BoxLayout, JTextField padding

I've created simple JDialog to gain initial data for my application. Elements (JLabel, JTextField and JButton) are arranged by BoxLayout inside the BorderLayout. (Code at the end). So far it looks like this:
I have two problems:
I would like to center JButton in it's row. I tried startBtn.setAlignmentX(Component.CENTER_ALIGNMENT);, but it doesn't work properly, mess appears.
I want to add some left/right padding to TextField. First solution from this topic works fine, but other elements are moved right left padding value.
Can anybody give a hint how to place it? I'm new to Java and have no idea.
Here's code of my InitDialog class:
public class InitDialog extends JDialog {
JTextField dataTF;
JButton startBtn;
public InitDialog(JFrame owner) {
super(owner, "Rozpocznij test", Dialog.ModalityType.DOCUMENT_MODAL);
initUI();
}
public final void initUI() {
System.out.println("InitDialog::initUI");
JPanel outer = new JPanel(new BorderLayout());
JPanel inner = new JPanel();
outer.setBorder(new EmptyBorder(new Insets(20, 20, 20, 20)));
JLabel msg = new JLabel("<html>Podaj ilości liczb w zestawach testowych<br />(przedzielone średnikiem):");
inner.add(msg);
inner.add(Box.createVerticalStrut(15));
dataTF = new JTextField();
dataTF.setBorder(null);
dataTF.setText("50; 100; 200");
inner.add(dataTF);
inner.add(Box.createVerticalStrut(15));
startBtn = new JButton("Rozpocznij test");
inner.add(startBtn);
inner.setLayout(new BoxLayout(inner, BoxLayout.Y_AXIS));
outer.add(inner);
add(outer);
setSize(300, 180);
//setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setResizable(false);
setLocationRelativeTo(getRootPane());
}
}
BoxLayout alignment is not what you think it is.
To get what you want this is the line you need
msg.setAlignmentX(Component.CENTER_ALIGNMENT);

Categories