I have the following code taken from GeeksforGeeks that displays the contents of a 2-d array in JTable using JScrollPane:
public class JTableExamples {
// frame
JFrame f;
// Table
JTable j;
// Constructor
JTableExamples()
{
// Frame initiallization
f = new JFrame();
// Frame Title
f.setTitle("JTable Example");
// Data to be displayed in the JTable
String[][] data = {
{ "Kundan Kumar Jha", "4031", "CSE" },
{ "Anand Jha", "6014", "IT" }
};
// Column Names
String[] columnNames = { "Name", "Roll Number", "Department" };
// Initializing the JTable
j = new JTable(data, columnNames);
j.setBounds(30, 40, 200, 300);
// adding it to JScrollPane
JScrollPane sp = new JScrollPane(j);
f.add(sp);
// Frame Size
f.setSize(500, 200);
// Frame Visible = true
f.setVisible(true);
}
What I am trying to do is add a simple Component (like JButton) underneath the table but it does not seem to work. I tried modifying the code by adding the JButton to JPanel and adding JPanel to the frame:
JButton button = new JButton("Back");
JPanel panel = new JPanel();
panel.add(button);
f.add(sp);
f.add(panel);
But this simply deletes the entire table and replaces it with a single button. I also tried adding the button to JPanel and adding that JPanel to JScrollPane:
JButton button = new JButton("Back");
JPanel panel = new JPanel();
panel.add(button);
sp.add(panel);
f.add(sp);
But this did not seem to change anything. I also tried to tinker with preferred and maximum size of JScrollPanel to no avail - it always occupies the entire screen and prevents JButton from appearing on the screen.
Not shooting for design here, just functionality: have a JButton appear underneath my JTable. Any suggestions will be greatly appreciated. Thank you in advance!
The default layout manager of a JFrame is the BorderLayout.
f.add(sp);
f.add(panel);
When you don't specify a constraint for the BorderLayout the CENTER is assumed. You can only have a single component added to the CENTER.
Instead your code should be:
f.add(sp, BorderLayout.CENTER);
f.add(panel, BorderLayout.PAGE_END);
Note the default layout manager for a JPanel is the FlowLayout. So the button will be horizontally centered in the panel.
Also, instead of using a JPanel, try adding the button directly to the PAGE_END of the frame to see the difference.
Read the section from the Swing tutorial on Using Layout Manager for more information and examples for using each of the different layout managers to understand the differences of the above suggestions.
Edit:
Is there a way to decrease the height of the table
If you know you have a small table then you can use:
table.setPreferredScrollableViewportSize(table.getPreferredSize());
This will make the scroll pane the size of the table.
Then you use:
//f.setSize(500, 200);
f.pack();
Now all components will be displayed at their preferred size.
Related
I have a JPanel. Inside Panel I have kept one JLabel and three JCheckBox.
I want to keep all the checkBox in one line after JLabel. Here is the sample code and some screenshots.
Output 1
Output 2
When i change to X_AXIS it is coming everything in one line and when i switch to Y_AXIS then it is coming new line means vertically.
But my requirement is all the checkbox should come next line means after JLabel.
JLabel should come in line and all the checkBox should come in one line.
public class CheckBoxWithJLabel {
public static void main(String[] args) {
JFrame f= new JFrame("CheckBox Example");
JPanel panel = new JPanel();
panel.setBounds(40,80,600,200);
JCheckBox chk_Embrodary=new JCheckBox("Embrodary");
JCheckBox chk_Cutting=new JCheckBox("Cutting");
JCheckBox cb_Sewing=new JCheckBox("Sewing");
panel.setLayout(new javax.swing.BoxLayout(panel, javax.swing.BoxLayout.X_AXIS));
JLabel lblHeader=new JLabel("Job Work Process Selection");
panel.add(lblHeader);
panel.add(chk_Embrodary);
panel.add(chk_Cutting);
panel.add(cb_Sewing);
f.add(panel);
f.setSize(600,400);
f.setLayout(null);
f.setVisible(true);
}
}
I want this output like
this
How to solve this problem?
I would highly suggest you to have a look through the Java Swing Tutorial, especially the Laying Out Components Within a Container section, since it seems you lack some basic understanding of how Swing and its Layout Managers are supposed to be used.
Regarding your problem:
Currently, you are using a single BoxLayout, which " puts components in a single row or column". You only want that behavior for your JCheckBoxes though, and not for your JLabel. Keeping this in mind, the solution is to split up your components and to not put all of them in a single JPanel. Doing this will grant you more flexibility in how you design your GUI, since you can use multiple layouts in different nested panels.
You could do something like this (explanation in the code comments):
public static void main(String[] args) {
JFrame f = new JFrame("CheckBox Example");
// add a Y_AXIS boxlayout to the JFrames contentpane
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));
JCheckBox cbEmbrodary = new JCheckBox("Embrodary");
JCheckBox cbCutting = new JCheckBox("Cutting");
JCheckBox cbSewing = new JCheckBox("Sewing");
// no need to set the bounds, since the layoutmanagers will determine the size
JPanel labelPanel = new JPanel(); // default layout for JPanel is the FlowLayout
JLabel lblHeader = new JLabel("Job Work Process Selection");
labelPanel.add(lblHeader); // JPanel for the label done
// JPanel for the comboboxes with BoxLayout
JPanel cbPanel = new JPanel();
cbPanel.setLayout(new BoxLayout(cbPanel, BoxLayout.X_AXIS));
cbPanel.add(cbEmbrodary);
cbPanel.add(cbCutting);
cbPanel.add(cbSewing);
f.add(labelPanel);
f.add(cbPanel);
// No need to set the size of the JFrame, since the layoutmanagers will
// determine the size after pack()
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
Output:
Sidenotes:
Don't set fixed sizes via setSize() or setBounds() to your components. Swing is designed to be used with appropariate LayoutManagers, and if you do that, calling pack() on the JFrame before setting it visible will layout the components and determine their appropriate size. (Also, don't use null-layout for the same reasons)
If you need the JLabel to not be centered but left aligned, like in your screenshot, then use the following:
FlowLayout layout = (FlowLayout) labelPanel.getLayout();
layout.setAlignment(FlowLayout.LEFT);
I want to increase the width that the table is covering On Jpanel.
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setTitle("Person Table");
jf.setSize(1100, 700);
JPanel jp1 = new JPanel();jp1.setBackground(Color.green);
JPanel jp2 = new JPanel(); jp2.setBackground(Color.red);
jp1.setSize(1100, 400);
jp2.setSize(980, 200);
JTable jt = new JTable(data,columnNames); jt.setSize(900, 350);
jt.setBackground(Color.ORANGE);
// Add table to JScrollpane
JScrollPane sp = new JScrollPane(jt); sp.setSize(1000, 380);
sp.setBackground(Color.CYAN);
jp1.add(sp);
jf.add(jp1);
jf.add(jp2);
jf.setVisible(true);
This is the output
I noticed that IF I don't use Scroll pan the Column name disappears and size increases..
But I also want the column name to appear..
Keep the scroll pane, and replace jp1 with it,
AKA Change:
jf.add(jp1);
to
jf.add(jsp);
This will make the table take up the whole green area*. If this isn't what you want, use nested layouts.
*Depending on the LayoutManager. In this case, FlowLayout is used which does not resize the component. Were you using a GridLayout or BorderLayout, the entire green area would be filled.
This is my code:
frame2 = new JFrame("Confirmation");
frame2.setLayout(new BorderLayout());
JRadioButton y,n,c;
panel = new JPanel();
ButtonGroup buttonGroup = new ButtonGroup();
y = new JRadioButton("Add");
buttonGroup.add(y);
panel.add(y);
n = new JRadioButton("Update");
buttonGroup.add(n);
panel.add(n);
c = new JRadioButton("Delete");
buttonGroup.add(c);
panel.add(c);
y.setSelected(true);
b1=new JButton();
b1.setBounds(300,100,2,2);
b1.setIcon(new ImageIcon(searchresult.class.getResource("/images/yes.png")));
b2=new JButton();
b2.setBounds(100,10,2,2);
b2.setIcon(new ImageIcon(searchresult.class.getResource("/images/no.png")));
panel.add(b1);
panel.add(b2);
frame2.add(panel);
frame2.setSize(182,150);
frame2.setVisible(true);
Right now this gives me the following output
whereas I want this
with an increased width but I am not able to do it..Could anyone provide me with further details that could help me
JPanel uses a FlowLayout by default, which, as the name suggests, layouts out components one after the after, in a flow...
Two choices. Use a compound layout, using BorderLayout as the base, create JPanel that uses a GridLayout for the radio buttons (using 0 rows and 1 column), add this to the CENTER position of the base panel.
Create a second JPanel using a FlowLayout and your buttons to it. Add this to the SOUTH position of the base pane.
Second choice is to use a GridBagLayout
Take a look at Laying out Components within a Container for more details
I have a Java application that connects to a device and shows the log in a JTextArea. I want the JTextArea to be scrollable, which I have achieved by putting it inside a JScrollPane. The JScrollPane containing the JTextArea is in the CENTER part of a BorderLayout. I use pack() to set the JFrame's size just before it is shown. However, this has some problems:
With no height set for the JTextArea it is very thin, and the text can't be seen very well (in the second picture there is actually text):
With a preferred size set for the JTextArea it seems to work fine at first. But when there is more text the scrollbars do not appear as expected. They appear when the JFrame is resized down regardless of the amount of text in the JTextArea. This also doesn't show all the text via scrolling.
Also, setting a minimum height doesn't help; it leads to the same result as in the first case.
My code for initializing the frame:
JButton connectBtn, disconnectBtn;
JTextArea logArea;
public MyApplication() throws HeadlessException {
super();
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new MyWindowListener()); // Disconnect and exit on close
setLayout(new BorderLayout());
connectBtn = new JButton("Connect");
disconnectBtn = new JButton("Disconnect");
disconnectBtn.setEnabled(false);
connectBtn.addActionListener(new ConnectListener()); // Connects to device
disconnectBtn.addActionListener(new DisconnectListener()); // Disconnects from device
logArea = new JTextArea();
logArea.setEditable(false);
// Whatever fixes the problem goes here... e.g.
// logArea.setPreferredSize(new Dimension(100, 200));
JPanel buttons = new JPanel(new BorderLayout());
buttons.add(connectBtn, BorderLayout.LINE_START);
buttons.add(disconnectBtn, BorderLayout.LINE_END);
add(buttons, BorderLayout.PAGE_START);
add(new JScrollPane(logArea), BorderLayout.CENTER);
pack();
setVisible(true);
}
Don't play with the sizes.
Specify the rows/column that you want in the text area and the text area will calculate its own preferred size.
//logArea = new JTextArea();
logArea = new JTextArea(5, 20);
I had problem using a very simple frame containing two JPanel.
The problem is on the layout of the Center JPanel that contains four JButton.
How can I set a better size for buttons or directly for JPanel that uses the GridLayout. On the picture the problem:
alt http://img42.imageshack.us/img42/4601/horrible.jpg
!
Here the code: ` JFrame window = new JFrame("Horrible! LOL");
JTextField textField = new JTextField("");
textField.setPreferredSize(new Dimension(200,20));
JPanel textPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
textPanel.add(textField);
window.add(textPanel, BorderLayout.NORTH);
JButton plus = new JButton("+");
//plus.setPreferredSize(new Dimension(50,50)); nothing would change
JButton minus = new JButton("-");
JButton per = new JButton("x");
JButton divide = new JButton("/");
JPanel prova = new JPanel(new GridLayout(2,2,10,10));
Dimension d = new Dimension(20,20);
prova.setMaximumSize(d); // nothing changed!
prova.add(plus);
prova.add(minus);
prova.add(per);
prova.add(divide);
window.add(prova, BorderLayout.CENTER);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(250,300);
window.setResizable(false);
window.setVisible(true);`
Which is a good solution?
Kind regards
Unfortunately gridlayout doesent respect preferred sizes. But still if you want to stick to grid layout then you can try something like this:
public static JComponent wrap(JComponent comp)
{
JPanel panel = new JPanel();
panel.add(comp);
return panel;
}
And then instead of direclty adding in to prova add like this:
prova.add(wrap(plus));
prova.add(wrap(minus));
prova.add(wrap(per));
prova.add(wrap(divide));
Tested, Works perfect!!
There are other better ways though
That's what happen to me:
It's definitely attached to the upper edge of the grid.
alt text http://img96.imageshack.us/img96/9431/stillnot.jpg
Even if in this case, in the wrap method I can set the preferredSize of buttons/comp, every buttons is on its own edge. What about others solutions. How would you position buttons for a calculator?
Kind regards and thanx angain!