i am trying to set size of JButton, but by default it take whole frame, it's height easily set but i can't set it's width & why its behaving like that i don't know.
my code :
JButton btnNewButton = new JButton("");
btnNewButton.setPreferredSize(new Dimension(32,0));
ImageIcon icon = new ImageIcon(this.getClass().getResource("/images/images_Left.png"));
btnNewButton.setIcon(icon);
boxTlacitek.add(btnNewButton);
getContentPane().add(btnNewButton, BorderLayout.NORTH);
any suggestion please ?
Change the layout. Try adding the button to another JPanel then add the panel the frame. BorderLayout will stretch the button across the available width of the panel when the component is placed in the NORTH or SOUTH position
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestBorderLayout {
public static void main(String[] args) {
new TestBorderLayout();
}
public TestBorderLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JButton fat = new JButton("Fat");
JButton skinny = new JButton("Skinny");
JPanel buttonPane = new JPanel();
buttonPane.add(skinny);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(fat, BorderLayout.NORTH);
frame.add(buttonPane, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
getContentPane().setLayout(null);
//setBounds(x,y,width,height)
btnNewButton.setBounds(10,10,250,100);
getContentPane().add(btnNewButton);
Related
I want split my Frame into two JPanel and the right JPanel serve as a textarea used to input and display.
However, I can't input anything in it and it can't display any thing.
the code as below:
JPanel jp1, jp2;
public DemoFrame() {
jp1 = new JPanel();
jp2 = new JPanel();
JLabel label = new JLabel("text");
JTextArea ta = new JTextArea(100,100);
ta.setText("some text");
ta.setSize(300, 300);
jp2.add(label);
jp2.add(ta);
JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jp1, jp2);
this.getContentPane().add(jsp);;
setBounds(300, 200, 500, 500);
setVisible(true);
jsp.setDividerLocation(0.5);//
}
the output as below(it doesnt display anything):
Congratulations, you've fallen victim to a number of conspiring issues.
The main culprit is FlowLayout, which is the default layout manager for JPanel. Essentially, when you add your, rather large, JTextArea to the panel, the FlowLayout is trying to honour the preferred size as best as it can within the constraints of the available space. For reasons I'm not 100% sure of, that means laying out the component beyond the visible bounds of the container.
If you type enough text, you will begin to see it.
While there are a number of ways you might fix this, they are basically the same solution - use a different layout manager.
For this example, I've just used a BorderLayout instead
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
private JPanel jp1, jp2;
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
jp1 = new JPanel();
jp2 = new JPanel(new BorderLayout());
JLabel label = new JLabel("text");
JTextArea ta = new JTextArea(50, 50);
ta.setText("some text");
jp2.add(label, BorderLayout.NORTH);
jp2.add(new JScrollPane(ta));
JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jp1, jp2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(jsp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
package swingtraining;
import static java.awt.Color.BLACK;
import static java.awt.Color.RED;
import java.awt.EventQueue;
import static java.awt.Font.BOLD;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
public class JFrameWithAButton extends JFrame {
public JFrameWithAButton(){
setSize(400,400);
setTitle("Swing is hard");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String args[]){
JPanel Jp1 = new JPanel();
Jp1.setOpaque(true);
Jp1.setBackground(RED);
JButton Jbt = new JButton();
Jbt.setLayout(null);
Jbt.setSize(200,200);
Jbt.setBounds(new Rectangle(new Point(200, 200)));
Jbt.setText("Hello!");
EventQueue.invokeLater(new Runnable(){
public void run(){
JFrameWithAButton ex = new JFrameWithAButton();
ex.setVisible(true);
ex.add(Jp1);
Jp1.add(Jbt);
}
});
}
}
Sorry if the code's a bit mom's spaghetti-esque, but I just can't crack this cookie >.> Even with layout set to null it doesn't move. Any suggestions of how I get this JButton to not only move to the middle of the window but also grow 200 by 200 pixels?
Any suggestions of how I get this JButton to not only move to the middle of the window but also grow 200 by 200 pixels?
I can think of a few, none of which use null layouts
GridBagConstraints
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.ipadx = 200;
gbc.ipady = 200;
add(new JButton("Hello"), gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
JButton#setMargin
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
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();
JButton btn = new JButton("Hello");
btn.setMargin(new Insets(100, 100, 100, 100));
add(btn);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
EmptyBorder
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
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 BorderLayout());
setBorder(new EmptyBorder(50, 50, 50, 50));
JButton btn = new JButton("Hello");
add(btn);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
You could use combination of them, maybe using an EmptyBorder and GridBagConstraints to further constrain the layout.
The great benefit of these examples, is, for the most part, if the font size changes or the rendering requirements for the fonts change, the layout is capable of compensating
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
And because it's always a fun read, Why is it frowned upon to use a null layout in SWING?
if you wanna define any component size manually you have to set the mother component's layout: null
so you have to set Jframe layout null to define Jpanel size and location
then you have to set JPanel layout null to define Jbutton size and location in it
final JPanel Jp1 = new JPanel();
Jp1.setOpaque(true);
Jp1.setBackground(RED);
Jp1.setLayout(null);
final JButton Jbt = new JButton();
// Jbt.setLayout(null); not needed!
Jbt.setBounds(10, 10, 100, 40);
// Jbt.setBounds(new Rectangle(new Point(200, 200))); not in this style
Jbt.setText("Hello!");
Jp1.add(Jbt);
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrameWithAButton ex = new JFrameWithAButton();
ex.setVisible(true);
ex.add(Jp1);
}
});
don't forget to define size and location both when you are adding a component in a null layout Jpanel or Jframe and ...
Lets say i have 2 GUI panels A and B
In Panel A, I have a jTextArea that you can input a String ,
and a jbutton that if it is pressed, it appends the String inside a jTextArrea on a jTextField that is inside Panel B
What i want to do is make the String append on Panel B after waiting 2 seconds
without having the Thread Going on to Sleep
It has to be able to input another string into jTextArea during the wait period
How do i do this without using Thread.sleep()?
Start by taking a look at Concurrency in Swing, How to use Swing Timers and Worker Threads and SwingWorker to understand the issues and the possible solutions.
If you really don't want to use Thread#sleep (which you could use with a SwingWorker), a Swing Timer is probably the best solution. It allows you to setup a callback after a given delay (you can also repeat the callback, but in this case, we only need it once).
import java.awt.BorderLayout;
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.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
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 {
private JTextField field;
private JTextArea ta1;
private JTextArea ta2;
private JButton btn;
private Timer timer;
public TestPane() {
JPanel panelA = new JPanel(new BorderLayout());
JPanel panelB = new JPanel(new BorderLayout());
setLayout(new GridLayout(1, 2));
add(panelA);
add(panelB);
field = new JTextField(10);
ta1 = new JTextArea(10, 20);
ta1.setEditable(false);
btn = new JButton("Add");
panelA.add(field, BorderLayout.NORTH);
panelA.add(new JScrollPane(ta1));
panelA.add(btn, BorderLayout.SOUTH);
ta2 = new JTextArea(10, 20);
ta2.setEditable(false);
panelB.add(new JScrollPane(ta2));
ActionListener startListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta1.append(field.getText() + "\n");
if (!timer.isRunning()) {
field.setEnabled(false);
btn.setEnabled(false);
timer.start();
}
}
};
field.addActionListener(startListener);
btn.addActionListener(startListener);
timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta2.append(field.getText() + "\n");
field.setEnabled(true);
btn.setEnabled(true);
field.setText(null);
field.requestFocusInWindow();
}
});
timer.setRepeats(false);
}
}
}
I'm looking for a way to set the display of a JTextField to take up the entire width of the JPanel that contains it.
The only method I've been able to find to do this is the setColumns() method combined with a getWidth() method called on the JPanel after the pack() and setVisible() methods are called. But when I do this the JTextField ends up much larger than the JPanel that encloses it. My assumption on why this happens is that the getWidth() returns that size of the JPanel in pixels, and the columns in the JTextField are all larger than a pixel.
I'm not even looking for the field to dynamically resize, just to be as wide as the JPanel at the start of the program
Any help greatly appreciated
Make use of an appropriate layout manager...
Remember, it's not the responsibility of the component to decide how big it should, that's the responsibility of the layout manager, the component can only provide hints about how big it would like to be...
For example, you could do this with a GridBagLayout...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
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() {
JTextField field = new JTextField(10);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(field, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Take a look at Laying Out Components Within a Container for more details
I am creating a JFrame object with some JPanels next to each other side by side.
I want the JPanels to have a 15px margin, etched border, and 15px padding. At first I thought that this would be something really intuitive just like the HTML box model, so I tried to create CompoundBorder inside a CompoundBorder but that wouldn't work.
Here's my code:
import java.awt.Dimension;
import javax.swing.*;
public class StackOverFlowExample extends JFrame {
public static void main() {
stackOverFlowExample window = new stackOverFlowExample();
window.setVisible(true);
}
public StackOverFlowExample() {
// create buttons
JButton foo = new JButton("foo");
JButton bar = new JButton("bar");
JButton foo2 = new JButton("foo2");
JButton bar2 = new JButton("bar2");
// create panels and add buttons to them
JPanel left = new JPanel();
left.setBorder(BorderFactory.createEtchedBorder());
left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS));
left.add(foo);
left.add(bar);
JPanel right = new JPanel();
right.setBorder(BorderFactory.createEtchedBorder());
right.setLayout(new BoxLayout(right, BoxLayout.PAGE_AXIS));
right.add(foo2);
right.add(bar2);
// add panels to frame
this.getContentPane().setLayout(new BoxLayout(
getContentPane(), BoxLayout.LINE_AXIS));
this.getContentPane().add(left);
this.getContentPane().add(right);
// finalize layout
this.setPreferredSize(new Dimension(150,150));
this.pack();
this.setVisible(true);
}
}
I'm aware that I could have just used GridBagConstraints or JButton.setMargin() to create the padding, and then use CompoundBorder to create the etched border with an empty border. What if I don't want to make my code look messy with those techniques though?
I'm not sure what problems you might be having, as you've not supplied an example of what you've tried, but the basic process would be to...
Create the inner border requirements (EtchedBorder wrapping a EmptyBorder), for example, new CompoundBorder(emptyBorder, etchedBorder)
Create the outer border requirements (EmptyBorder wrapping the inner compound border), for example, new CompoundBorder(inner, emptyBorder);
Apply this outer border to the component...
As an example...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
public class Test1 {
public static void main(String[] args) {
new Test1();
}
public Test1() {
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());
EmptyBorder emptyBorder = new EmptyBorder(15, 15, 15, 15);
EtchedBorder etchedBorder = new EtchedBorder();
CompoundBorder inner = new CompoundBorder(emptyBorder, etchedBorder);
CompoundBorder outter = new CompoundBorder(inner, emptyBorder);
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(outter);
panel.add(new JButton("Hello"));
add(panel);
}
}
}
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
public class ThreePartBorder {
public static void main(String[] args) {
final BufferedImage bi = new BufferedImage(
400, 100, BufferedImage.TYPE_INT_RGB);
Runnable r = new Runnable() {
#Override
public void run() {
JLabel l = new JLabel(new ImageIcon(bi));
Border twoPartBorder = new CompoundBorder(
new EmptyBorder(15, 15, 15, 15),
new EtchedBorder());
Border threePartBorder = new CompoundBorder(
twoPartBorder,
new EmptyBorder(15, 15, 15, 15));
l.setBorder(threePartBorder);
JFrame f = new JFrame("Three Part Border");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(l);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I came back and just realized I asked a dumb question haha. Both answers above are very helpful and helped me solve the problem so I accepted one of them. Here's my solution after reading the two answers...
left.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(10,10,10,10), // margin
BorderFactory.createEtchedBorder() // border
),
BorderFactory.createEmptyBorder(50,50,50,50) // padding
));
right.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(10,10,10,10), // margin
BorderFactory.createCompoundBorder(
BorderFactory.createEtchedBorder(), // border
BorderFactory.createEmptyBorder(50,50,50,50) // padding
)
));