I am a student learning java ahead of my comp sci class, and my teacher knows nothing about JFrames or JButtons, so I'm reaching out here. This is my overarching program to learn about JFrames, the first menu it opens up just fine, sometimes it will set the bounds of buttons correctly, but sometimes it ignores it and fills the frame, sometimes one button, sometimes its different buttons, I couldn't find any other threads on here with the same situation, so I figured I would ask.
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.Random;
public class programToEndAllPrograms {
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(400,400);
JLabel title = new JLabel("Choose a Program");
JButton TempConverter = new JButton();
TempConverter.setText("Temperature Converter");
TempConverter.setBounds(50,155,200,50);
TempConverter.setLayout(null);
frame.add(TempConverter);
JButton CurrentTime = new JButton();
CurrentTime.setText("Current Time");
CurrentTime.setBounds(50,105,200,50);
CurrentTime.setLayout(null);
frame.add(CurrentTime);
JButton RussianRoulette = new JButton();
RussianRoulette.setText("Russian Roulette");
RussianRoulette.setBounds(50,55,200,50);
RussianRoulette.setLayout(null);
frame.add(RussianRoulette);
JButton DaysSinceLastTrinket = new JButton();
DaysSinceLastTrinket.setText("Days Since Last Trinket");
DaysSinceLastTrinket.setBounds(50,15,200,50);
DaysSinceLastTrinket.setLayout(null);
frame.add(DaysSinceLastTrinket);
frame.add(title);
JButton SimpleCalculator = new JButton();
SimpleCalculator.setText("Simple Calculator");
SimpleCalculator.setBounds(50,205,200,50);
SimpleCalculator.setLayout(null);
frame.add(SimpleCalculator);
TempConverter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tempConverter();
}
});
SimpleCalculator.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
simpleCalculator();
}
});
CurrentTime.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
currentTime();
}
});
RussianRoulette.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
russianRoulette();
}
});
DaysSinceLastTrinket.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
daysSinceLastTrinket();
}
});
JOptionPane.showMessageDialog(frame, "Choose a program from the list:");
frame.setLayout(null);
frame.setVisible(true);
}```
Pixel perfect layouts are an illusion, too many factors go into determining how best a component should be sized and positioned.
Take the time to learn and understand how to make use of the available layout managers - see Laying Out Components Within a Container. Remember, you're not stuck to a single container/layout, you can compound these together to produce very complex UIs
For example, this is what your UI produces (when I fix the core issue)
But if I make use of an appropriate layout managers I can produce...
GridBagLayout
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
gbc.fill = gbc.HORIZONTAL;
gbc.ipadx = 8;
gbc.ipady = 8;
JLabel title = new JLabel("Choose a Program");
title.setHorizontalAlignment(JLabel.CENTER);
add(title, gbc);
JButton TempConverter = new JButton();
TempConverter.setText("Temperature Converter");
add(TempConverter, gbc);
JButton CurrentTime = new JButton();
CurrentTime.setText("Current Time");
add(CurrentTime, gbc);
JButton RussianRoulette = new JButton();
RussianRoulette.setText("Russian Roulette");
add(RussianRoulette, gbc);
JButton DaysSinceLastTrinket = new JButton();
DaysSinceLastTrinket.setText("Days Since Last Trinket");
add(DaysSinceLastTrinket, gbc);
JButton SimpleCalculator = new JButton();
SimpleCalculator.setText("Simple Calculator");
add(SimpleCalculator, gbc);
}
}
}
But, I appreciate that GridBagLayout is one of the most complex (and flexible) layout managers, but, we can try...
"Compound" layout
We can isolate functionality to individual components, which can make use of their own layout managers, allowing us to focus on the individual components needs and then build up much more complex layouts...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new BorderLayout());
JLabel title = new JLabel("Choose a Program");
title.setBorder(new EmptyBorder(8, 8, 8, 8));
title.setHorizontalAlignment(JLabel.CENTER);
add(title, BorderLayout.NORTH);
JPanel optionsPane = new JPanel(new GridLayout(-1, 1));
optionsPane.setBorder(new EmptyBorder(8, 8, 8, 8));
JButton TempConverter = new JButton();
TempConverter.setMargin(new Insets(8, 8, 8, 8));
TempConverter.setText("Temperature Converter");
optionsPane.add(TempConverter);
JButton CurrentTime = new JButton();
CurrentTime.setText("Current Time");
CurrentTime.setMargin(new Insets(8, 8, 8, 8));
optionsPane.add(CurrentTime);
JButton RussianRoulette = new JButton();
RussianRoulette.setText("Russian Roulette");
RussianRoulette.setMargin(new Insets(8, 8, 8, 8));
optionsPane.add(RussianRoulette);
JButton DaysSinceLastTrinket = new JButton();
DaysSinceLastTrinket.setText("Days Since Last Trinket");
DaysSinceLastTrinket.setMargin(new Insets(8, 8, 8, 8));
optionsPane.add(DaysSinceLastTrinket);
JButton SimpleCalculator = new JButton();
SimpleCalculator.setText("Simple Calculator");
SimpleCalculator.setMargin(new Insets(8, 8, 8, 8));
optionsPane.add(SimpleCalculator);
add(optionsPane);
}
}
}
nb: If you want to change the order of the buttons, then change the order in which they are added 😉
Related
I have a button panel and I want a space of 25px between the buttons and a right margin of 5px and a left margin of 5px (the button at the right would be at 5 pixels of the window border).
Flow layout set a gap of the same size everywhere. Gridlayout permit to do that, but then all the buttons have the same size and it is no that I want. The only solution I found is to set Flow layout with hgap=0. then I had an emptyMargin and I but a rigid area before each button, but I think this solution is a bad practice.
What is the best solution to do that ?
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FlowLayoutDemo extends JFrame{
FlowLayout experimentLayout = new FlowLayout(FlowLayout.LEFT, 25, 0);
public FlowLayoutDemo(String name) {
super(name);
}
public void addComponentsToPane(final Container pane) {
final JPanel compsToExperiment = new JPanel();
compsToExperiment.setLayout(experimentLayout);
experimentLayout.setAlignment(FlowLayout.TRAILING);
compsToExperiment.add(new JButton("Button 1"));
compsToExperiment.add(new JButton("Button 2"));
compsToExperiment.add(new JButton("Button 3"));
compsToExperiment.add(new JButton("Long-Named Button 4"));
compsToExperiment.add(new JButton("5"));
pane.add(compsToExperiment, BorderLayout.CENTER);
}
private static void createAndShowGUI() {
FlowLayoutDemo frame = new FlowLayoutDemo("FlowLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Consider using a GridBagLayout instead, it provides a greater amount of control and customisation.
See How to use GridBagLayout for more details.
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.insets = new Insets(5, 5, 5, 25);
gbc.fill = gbc.HORIZONTAL;
gbc.weightx = 1;
add(new JButton("Button 1"), gbc);
gbc.insets = new Insets(5, 0, 5, 25);
add(new JButton("Button 2"), gbc);
add(new JButton("Button 3"), gbc);
add(new JButton("Long-Named Button 4"), gbc);
gbc.insets = new Insets(5, 0, 5, 5);
add(new JButton("5"), gbc);
}
}
}
Note, the example forces the buttons too occupy ALL of the available space. If this doesn't meet your needs in particular, try playing around with the fill and weightx values
The best way is to use the GridBagLayout as it shown in example of MadProgrammer. But it also possible using FlowLayout. Here is the example:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FlowLayoutDemo extends JFrame {
FlowLayout experimentLayout = new FlowLayout(FlowLayout.LEFT, 5, 0);
public FlowLayoutDemo(String name) {
super(name);
}
public void addComponentsToPane(final Container pane) {
final JPanel compsToExperiment = new JPanel();
compsToExperiment.setLayout(experimentLayout);
experimentLayout.setAlignment(FlowLayout.TRAILING);
compsToExperiment.add(new JButton("Button 1"));
compsToExperiment.add(Box.createHorizontalStrut(20));
compsToExperiment.add(new JButton("Button 2"));
compsToExperiment.add(Box.createHorizontalStrut(20));
compsToExperiment.add(new JButton("Button 3"));
compsToExperiment.add(Box.createHorizontalStrut(20));
compsToExperiment.add(new JButton("Long-Named Button 4"));
compsToExperiment.add(Box.createHorizontalStrut(20));
compsToExperiment.add(new JButton("5"));
pane.add(compsToExperiment, BorderLayout.CENTER);
}
private static void createAndShowGUI() {
FlowLayoutDemo frame = new FlowLayoutDemo("FlowLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
If you want to get tricky so you don't need to play with all the constraints of GridBagLayout or add filler components you could do:
JPanel compsToExperiment = new JPanel(experimentLayout);
compsToExperiment.setBorder( new EmptyBorder(0, -20, 0, -20) );
This effectively decrease the space by 20 pixels around the left/right edges of the panel.
Also, just wanted to point out that you have:
FlowLayout experimentLayout = new FlowLayout(FlowLayout.LEFT, 25, 0);
...
experimentLayout.setAlignment(FlowLayout.TRAILING);
You set the layout to left aligned and then change it to trailing. This is a little confusing. You can just set it to trailing when you create the layout:
FlowLayout experimentLayout = new FlowLayout(FlowLayout.TRAILING, 25, 0);
I feel as beginner I may have bitten off too much in regards to application building. That said, I am working on developing an application for a friend that will have prompts where each JPanel will provide fields to create an object to be used later. What I would like to have happen is that when the panel loads, it displays one object creation panel and a button to dynamically add a new panel if the user wants to make multiples (the plus button would add the new panel).
I have drawn up something in paint to illustrate this:
By my very limited understanding, I can create a panel to hold these sub-panels, and then add a action listener to the '+' button to create new panels. The only way I could think to implement this is to create a constructor for the panel I want to add. Is this possible? Let me show you what I have:
package com.company;
import java.awt.*;
import javax.swing.*;
/**
* Created by Travis on 3/1/2015.
*/
public class MainSnakeGui extends JFrame{
protected int panelCount;
//row 1
JPanel row1 = new JPanel();
JLabel splitSnakeLabel = new JLabel("Create a Split Snake", JLabel.CENTER);
//row 2
JPanel row2 = new JPanel();
JButton addButton = new JButton("+");
public MainSnakeGui() {
super("Snake Channels");
setSize(550, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout layout = new GridLayout(5, 1, 10, 10);
setLayout(layout);
FlowLayout layout1 = new FlowLayout(FlowLayout.CENTER, 10, 10);
row1.setLayout(layout1);
row1.add(splitSnakeLabel);
add(row1);
GridLayout layout2 = new GridLayout(1, 2, 10, 10);
row2.setLayout(layout2);
row2.add(addButton);
MainSnakeConstructor snakePanel = new MainSnakeConstructor();
row2.add(snakePanel);
add(row2);
setVisible(true);
}
public static void setLookAndFeel () {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
}
}
public static void main(String[] arg) {
MainSnakeGui.setLookAndFeel();
MainSnakeGui frame = new MainSnakeGui();
}
}
Here is the constructor:
package com.company;
import javax.swing.*;
import java.awt.*;
/**
* Created by Travis on 3/1/2015.
*/
public class MainSnakeConstructor extends JFrame {
public MainSnakeConstructor () {
JPanel splitSnakeRow = new JPanel();
JLabel snakeNameLabel = new JLabel("Snake Name");
JLabel channelCountLabel = new JLabel("Channel Count");
JCheckBox artistSuppliedCheckBox = new JCheckBox("Artist Supplied?");
JTextField snakeNameTextField = new JTextField(30);
JTextField channelCountTextField = new JTextField(3);
GridLayout layout = new GridLayout(3,2,10,10);
splitSnakeRow.setLayout(layout);
splitSnakeRow.add(snakeNameLabel);
splitSnakeRow.add(channelCountLabel);
splitSnakeRow.add(artistSuppliedCheckBox);
splitSnakeRow.add(snakeNameTextField);
splitSnakeRow.add(channelCountTextField);
add(splitSnakeRow);
}
}
Think about it differently. You want a button that allows you to add new panels, so you really only need a single button.
From there, you need some kind common panel which provides the functionality you want to the user (the creation panel). Then, when the user clicks the add button, you create a new creation panel and add it to the container been used to display them, for example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton btnAdd = new JButton("+");
setLayout(new BorderLayout());
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
buttons.add(btnAdd);
add(buttons, BorderLayout.NORTH);
JPanel content = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weighty = 1;
content.add(new JPanel(), gbc);
add(new JScrollPane(content));
btnAdd.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CreationPane pane = new CreationPane();
int insertAt = Math.max(0, content.getComponentCount() - 1);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
content.add(pane, gbc, insertAt);
content.revalidate();
content.repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public static class CreationPane extends JPanel {
private static int count;
public CreationPane() {
setLayout(new GridBagLayout());
add(new JLabel("Make it so " + (count++)));
setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
}
}
}
Now having done all that, I prefer the VerticalLayout manager from SwingLabs, SwingX library, which basically does the same thing...
This class generates a window or frame(Im not too sure what the proper title would be) that has a back button and a ship select button on the left side. I would like to add a panel that takes up the right half of the frame. I am trying to add some more options specific to "Ship Selection" so I am assuming a panel is the correct way to go about it but am not entirely sure. Thanks in advance.
private class OptionsPanel extends JPanel{
private Galaga parent;
public OptionsPanel(Galaga p) {
super();
parent = p;
//layout components however you wish
setLayout(null);
JButton backButton = new JButton("<< Back");
backButton.setBounds(5, 20, 100, 20);
backButton.setFont(new Font("Arial", Font.PLAIN, 15));
backButton.setForeground(Color.white);
backButton.setBackground(Color.black);
backButton.setOpaque(true);
backButton.setBorderPainted(false);
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
parent.getLayeredPane().remove(parent.getOptionsPanel());
parent.getLayeredPane().add(parent.getButtonPanel(), new Integer(10));
parent.invalidate();
}
});
add(backButton);
JButton shipSelectButton = new JButton("Ship Selection");
shipSelectButton.setBounds(10, 60, 200, 40);
shipSelectButton.setFont(new Font("Arial", Font.PLAIN, 20));
shipSelectButton.setForeground(Color.white);
shipSelectButton.setBackground(Color.black);
shipSelectButton.setOpaque(true);
shipSelectButton.setBorderPainted(false);
shipSelectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(shipSelectButton);
}
}
}
The most basic option is to use a GridLayout
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class LayoutExamples {
public static void main(String[] args) {
new LayoutExamples();
}
public LayoutExamples() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2));
frame.add(new OptionsPanel());
frame.add(new OtherPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class OtherPane extends JPanel {
public OtherPane() {
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 200);
}
}
public class OptionsPanel extends JPanel {
public OptionsPanel() {
super();
//layout components however you wish
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
gbc.anchor = GridBagConstraints.NORTHWEST;
JButton backButton = new JButton("<< Back");
backButton.setFont(new Font("Arial", Font.PLAIN, 15));
backButton.setForeground(Color.white);
backButton.setBackground(Color.black);
backButton.setOpaque(true);
backButton.setBorderPainted(false);
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(backButton, gbc);
JButton shipSelectButton = new JButton("Ship Selection");
shipSelectButton.setFont(new Font("Arial", Font.PLAIN, 20));
shipSelectButton.setForeground(Color.white);
shipSelectButton.setBackground(Color.black);
shipSelectButton.setOpaque(true);
shipSelectButton.setBorderPainted(false);
shipSelectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
}
});
gbc.insets = new Insets(12, 8, 12, 12);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weighty = 1;
gbc.weightx = 1;
add(shipSelectButton, gbc);
}
}
}
Pixel perfect layouts are an illusion in modern UI design. You don't have control over how things like fonts or even a single line will be rendered. Differences in rendering pipelines and DPI settings (for example) will change the metrics/size requirements of the components between platforms.
Swing is designed to use layout managers, make appropriate use of them.
I created a JPanel and i have added a TitleBorder with BorderFactory but it's showing a blue line around the panel.
I would like to remove this line.
Any suggestions?
Thank you
never tried to extract this value from TitleBorders API, methods are protected, or by using UIManager
have to use LineBorder inside TitleBorder
simpliest syntax could be xxx.setBorder(new TitledBorder(new LineBorder(Color.ORANGE, 1), "label")); or get the Color from (for example) myPanel.getBackground() instread of Color.ORANGE
another options are (is possible)
move desciption (top, bottom.....)
change Font
change Foreground (Color for description)
more options and description in Oracle tutorial How to Use Borders (CompounBorders)
for example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
panel.setBorder(new TitledBorder(new LineBorder(Color.ORANGE, 1),
"Add Components At Runtime"));
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
});
}
}
The blue line (in metal) is the default border used by TitledBorder if none is given explicitly. You need to provide another border if you don't like the default, f.i. an EmptyBorder:
myPanel.setBorder(BorderFactory.createTitledBorder
(BorderFactory.createEmptyBorder(), someTitle));
I want to add textfields dynamically on the click of a button but the value to be fetched and the button are in one class and the panel where i want to add the textboxes and sliders adjacent to the are in a different class. Code is -
public class TipSplitting extends JPanel
JLabel lblNoOfGuests = new JLabel("No. Of guests");
lblNoOfGuests.setBounds(10, 26, 95, 14);
add(lblNoOfGuests);
private JTextField noofguests = new JTextField();
noofguests.setBounds(179, 23, 86, 20);
add(noofguests);
noofguests.setColumns(10);
JButton btnTiptailoring = new JButton("TipTailoring");
btnTiptailoring.setBounds(117, 286, 89, 23);
add(btnTiptailoring);
public class TipTailoring extends JPanel {}
In this class I need to create the text fields dynamically according to the no. entered. In the variable noofguests and the click of the button in the previous class.
I can't really see what the problem, but here some simple demo code of what you describe.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestDynamicallyAddedTextFields {
private void initUI() {
JFrame frame = new JFrame(TestDynamicallyAddedTextFields.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel textfieldContainerPanel = new JPanel();
textfieldContainerPanel.setLayout(new GridBagLayout());
JLabel nrOfGuests = new JLabel("Nr. of guests");
final JFormattedTextField textfield = new JFormattedTextField();
textfield.setValue(Integer.valueOf(1));
textfield.setColumns(10);
JButton add = new JButton("Add");
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (textfield.getValue() != null) {
addTextFieldsToPanel((Integer) textfield.getValue(), textfieldContainerPanel);
}
}
});
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));
panel.add(nrOfGuests);
panel.add(textfield);
panel.add(add);
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(textfieldContainerPanel));
frame.setSize(300, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
protected void addTextFieldsToPanel(Integer value, JPanel textfieldContainerPanel) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridheight = 1;
for (int i = 0; i < value; i++) {
textfieldContainerPanel.add(new JTextField(20), gbc);
}
textfieldContainerPanel.revalidate();
textfieldContainerPanel.repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestDynamicallyAddedTextFields().initUI();
}
});
}
}
And the result: