Java JButton Size - java

I know there are some other questions similar to this but I haven't seen my specific question answered. I want to change the size of a JButton WITHOUT changing the look. For example if I use setPreferredSize, I lose the white background color and rounded corners. I just want to remove the surrounding padding so the button is only slightly bigger then it's label.
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame jFrame = new JFrame("Label");
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
JPanel jPanel = new JPanel(new GridBagLayout());
JButton jButtonUp = new JButton("Upd");
//jButtonUp.setPreferredSize(new Dimension(30, 20));
jPanel.add(jButtonUp, gbc);
gbc.gridy = 1;
JButton jButtonDn = new JButton("Del");
//jButtonDn.setPreferredSize(new Dimension(30, 20));
jPanel.add(jButtonDn, gbc);
jFrame.add(jPanel);
jFrame.pack();
jFrame.setVisible(true);
Using Mac OSX Sierra.
What I have is this:
What I get with setPreferredSize is this:
What I want is this:

Check this answer here, Simply do
After the line:
JButton jButtonUp = new JButton("Upd");
Add:
jButtonUp.setBorder(null);
jButtonUp.setMargin(new Insets(0,0,0,0));
Then add the button to the panel:
jPanel.add(jButtonUp, gbc);

Related

Change JFrame background color

Created a JFrame and tried to change the background but it does not work.
I have looked at so many solutions here and on the Internet and it doesnt work , What is wrong in my code
JFrame frame = new JFrame("Process");
JLabel label = new JLabel("Please wait...");
JProgressBar pb = new JProgressBar();
pb.setIndeterminate(true);
pb.setBackground(new java.awt.Color(248, 201, 171));
frame.setBackground(new java.awt.Color(242, 186, 152));
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setBackground(new java.awt.Color(242, 186, 152));
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(10,10,10,10); // make spaces between components on screen
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 20;
panel.add(label, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 20;
panel.add(pb, c);
frame.add(panel);
frame.setVisible(true);
try frame.getContentPane().setBackground(new java.awt.Color(242, 186, 152));
don't work on the frame, work on the frame.getContentPane(). This is also where your sub panel and layout should be set. Besides, you use gridbag constraints but you never set a gridbag layout first. Meanwhile, you add to the frame and even if you did add to the content pane, you also didn't specify a content pane layout.
After doing changes in my code I found that the problem is caused by the GridBagConstraints c = new GridBagConstraints();
so i changed this by using panel.setLayout(null); then used setBounds to adjust the position of the components label.setBounds(100, 30, 250, 10);
and everything os ok

GridBagLayout not lining up

I have 5 JPanels lined up vertically. Each JPanel is filled with the same elements, but different values (JPanel, JButton, JLabel). I want them to look like this:
Panel Button Label
Panel Button Label
Buts it's turning out like this
Panel Button Label
Panel Button Label
The spacing is a little off, but the code is exactly the same for each container. How can I fix this?
public class AnswerChoice extends JPanel {
private static final long serialVersionUID = 1L;
private AnswerButton button;
private JLabel answerLabel;
public AnswerChoice(String imageURL) {
setBackground(Color.RED);
setLayout(new GridBagLayout());
button = new AnswerButton(imageURL);
answerLabel = new JLabel();
answerLabel.setFont(new Font("Times New Roman", Font.PLAIN, 32));
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel = new JPanel();
panel.setBackground(Color.ORANGE);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.weightx = 0.2;
add(panel, gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 2;
gbc.weightx = 0.0;
gbc.insets = new Insets(0, 0, 0, 30);
add(button, gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 3;
gbc.weightx = 0.8;
add(answerLabel, gbc);
}
}
The JLabel does have text in it but I set it somewhere else.
but the code is exactly the same for each container.
The layout is done independently for each container based on the components added to the containter. So the size of each component on the container matters. Each container doesn't know that you have 4 other containers.
I have 5 JPanels lined up vertically.
So then you need to create a single panel using a GridBagLayout and add all 15 components to that panel. Then all 3 columns will be sized based on the components in each of the 5 rows.
Or I see in your logic that you try to assign relative sizes to each of the 3 components as .2, 0, .8. In this case you could use the Relative Layout on each of the panels. Using the Relative Layout you would display the button at its preferred size and then use 0.2f and 0.8f as the contraints for the panel and label respectively.

Java - GridBagLayout position JLabel

I use a GridBagLayout and place a JLabel on it as the picture shows. I managed to set the size of the JLabel to the desired one via ipadx and ipady but I don't seem to work with the position of it. It seems it is always centered on the middle while I'd like to start from the red dot and don't reposition itself as I resize the window. What should I do?
Thanks. The code I use is also:
GridBagLayout gbl = new GridBagLayout();
setLayout(gbl);
GridBagConstraints gbc = new GridBagConstraints();
JLabel jl = new JLabel("This is a jlabel!", SwingConstants.CENTER);
jl.setBorder(BorderFactory.createLineBorder(Color.black));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.ipadx = 87;
gbc.ipady = 220;
add(jl, gbc);
I improved it... now you can work with insets to position that label around JFrame, but after some research I would recommend to choose different layout manager.
So your code would look like:
Dimension d = new Dimension(350, 400);
GridBagLayout gbl = new GridBagLayout();
JFrame frame = new JFrame("Heloo");
frame.setLayout(gbl);
GridBagConstraints gbc = new GridBagConstraints();
JLabel jl = new JLabel("This is a jlabel!", SwingConstants.CENTER);
jl.setBorder(BorderFactory.createLineBorder(Color.black));
gbc.ipadx = 87;
gbc.ipady = 220;
gbc.insets = new Insets(0, 0, 360, 340);// here work with JFrame size!!
Hope this code will help you :)

GridBagLayout - Height of one row causes the width of next row to change

The UI I am working on displays a panel which lets a user select a movie and play. There are controls to play, pause, etc.
The layout seems to look the way I want. The panel uses a GridBagLayout. Row 2 displays a text area for status messages and row 3 displays a panel with buttons and a progress bar.
The problem I am running into is that when I have too many lines of text in the text area, the buttons in row 3 wrap around. This is irrespective of the height of the outer frame.
The height in row 2 is affecting the width in row 3. I don't understand this behavior. I am wondering if someone can tell me what is it that I am doing wrong and how I can fix it? I have attached the code.
On a slightly different topic, if you are looking at the code, can you also suggest a way to leave a margin between the bottom-most component and the outermost panel?
Thank you in advance for your help.
Regards,
Peter
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
public MoviePanel() {
this.setLayout(new GridBagLayout());
this.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
this.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
this.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
this.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.weighty = 1.0;
c.insets.top = 10;
this.add(txtInfo, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 2;
c.weightx = 1.0;
this.add(controllerOuter, c);
}
I see several things in your code:
You force the preferredSize of the JButton's. If possible, I would remove that because this will often get you more problems than solutions. If you want to force the preferredSize, you should also pay attention to set the minimum and maximum sizes as well, otherwise you get weird behaviour like the one you are observing
You use a BoxLayout to display the controls. While this is perfectly acceptable, BoxLayout also relies on min/max size to perform the layout, which you did not set.
You use imbricated layouts. This is fine too, but why not use only the GridBagLayout of your MoviePanel?
Usually TextAreas are wrapped in JScrollPane, in case the text is too big. You can also setLineWrap(true) on the TextArea, so that it does not go too far on the right. By setting rows/columns on the TextArea, you will define its preferreSize (to prevent it from depending of the text it contains).
On your GridBagConstraints, the fill property can only be: NONE, VERTICAL, HORIZONTAL or BOTH (You used VERTICAL for one of them). Also, it is not needed to recreate a new instance, you can reuse the same GridBagConstraint over and over, it is automatically cloned by the LayoutManager when you set the constraint for the component.
Now for the solutions, I found several:
When you add the contollerOuter, also specify c.fill = GridBagConstraints.HORIZONTAL; (This is the easiest way to solve your issues)
When you set the preferredSize of the JButtons, also force their minimumSize to the same value.
Use only the GridBagLayout to layout all components. (This would be my favorite)
Replace the FlowLayout by a BoxLayout with a X_AXIS.
Rember that GridBagConstraints properties :
gridx, gridy: specifies the location
gridwidth, gridheight: specifies the colspan/rowspan
weightx, weighty: specifies who gets the extra horizontal/vertical space and in what proportion
anchor: specifies the alignement of the component withing its "cell", if the "cell" is bigger than the component
fill: specifies if the component should stretch to the cell width/height
Just adding one JPanel each for Center and Bottom will do the trick for you, so till your JTextArea your GridBagLayout will server the purpose and after that the BorderLayout of the MAIN JPanel will do. Moreover, adding JScrollPane also to the whole thing reduces the effort needed at other areas. Have a look at the code and output :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class JTextPaneExample extends JPanel
{
private Icon info = UIManager.getIcon("OptionPane.informationIcon");
private Icon error = UIManager.getIcon("OptionPane.errorIcon");
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JTextPane Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setBackground(Color.WHITE);
JPanel centerPanel = new JPanel();
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
centerPanel.setLayout(new GridBagLayout());
centerPanel.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
centerPanel.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
centerPanel.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
centerPanel.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
JScrollPane scroller = new JScrollPane();
scroller.setViewportView(txtInfo);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1.0;
c.insets.top = 10;
centerPanel.add(scroller, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
add(centerPanel, BorderLayout.CENTER);
add(controllerOuter, BorderLayout.PAGE_END);
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JTextPaneExample().createAndDisplayGUI();
}
});
}
}
Here is the output as you add more lines :

GridLayout Help in Java

I have a JPanel with the following code:
JPanel pane = new JPanel();
pane.setLayout(new GridLayout(3, 2, 10, 30));
final JTextField fileName = new JTextField();
pane.add(fileName);
JButton creater = new JButton("Create File");
pane.add(creater);
JButton deleter = new JButton("Delete File");
pane.add(deleter);
I was wondering, how do I make it so that the JTextField takes up two spaces on the GridLayout, while having the two buttons share a row by taking up one space each on the same line?
It is a hard to do with GridLyout. You have create wider cells (e.g. new GridLayout(2, 2, 10, 30), then add TextField to the fist cell. Then you have to create yet another panel with GridLayout(2, 1), put it into the cell in second line and add your button into 1 st cell of this nested grid layout.
Shortly you need GridLayout into other GridLayout.
There are better tools to implement this. First take a look on GridBagLayout. It is just to be sure that life is not always pick-nick :). Then take a look on alternative solutions like MigLayout. It is not a part of JDK but it really powerful tool that makes your life easier.
You cannot do column spans with GridLayout. I recomend you try GridBagLayout and GridBagConstraints
After trashing the suggestion of 3rd party layouts, and since I possess a malevolent hatred of GBL, I thought it was about to time to 'put my code where my mouth is' for public scrutiny (and trashing).
This SSCCE uses a nested layout.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class SimpleLayoutTest {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JPanel ui = new JPanel( new BorderLayout(20,20) );
// I would go for an EmptyBorder here, but the filled
// border is just to demonstrate where the border starts/ends
ui.setBorder( new LineBorder(Color.RED,15) );
// this should be a button that pops a JFileChooser, or perhaps
// a JTree of the existing file system structure with a JButton
// to prompt for the name of a new File.
final JTextField fileName = new JTextField();
ui.add(fileName, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 30));
ui.add(buttonPanel, BorderLayout.CENTER);
JButton creater = new JButton("Create File");
buttonPanel.add(creater);
JButton deleter = new JButton("Delete File");
buttonPanel.add(deleter);
JOptionPane.showMessageDialog(null, ui);
}
};
SwingUtilities.invokeLater(r);
}
}
Take a look at the tutorial on How to Use GridBagLayout.
Sample code:
JPanel pane = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
pane.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
final JTextField fileName = new JTextField();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 0;
pane.add(fileName, c);
JButton creater = new JButton("Create File");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 1;
pane.add(creater, c);
JButton deleter = new JButton("Delete File");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
pane.add(deleter, c);

Categories