I have, the same issue with two components JTextField and JComboBox, I assume the solution I'm looking for would solve it for all components.
I have set the size of the components to default thus their size fits the initial content I supplied to it. when I change the content of a component to exceeds the region of the component, I cannot see the whole text, and I would like my component to resize to fit the text.
How can I accomplish that?
Update:
The pack() on the frame only enlarged the text field, how can I do the same and enlarge the combo box?
Update:
private class ComboBoxRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 752379460716217273L;
Dimension maxSize=new Dimension();
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
Dimension size = getPreferredSize();
if(maxSize.width<size.width)
maxSize.width=size.width;
if(maxSize.height<size.height)
maxSize.height=size.height;
resolutionDescriptor_ComboBox.setPreferredSize(maxSize);
return this;
}
}
this works, not very efficient, but it is a first step, thing is, it does not take the button image into size considerations, so some of the text is still not shown, but the component resizes, do you have any suggestions?
Adam.
Answer:
This did the trick together with a pack(), no revalidation needed.
private class ComboBoxRenderer extends JLabel implements ListCellRenderer {
private static final long serialVersionUID = 752379460716217273L;
Dimension maxSize=new Dimension();
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
Dimension size = getPreferredSize();
if(maxSize.width<size.width) {
maxSize.width=size.width;
resolutionDescriptor_ComboBox.setPrototypeDisplayValue(value.toString());
}
if(maxSize.height<size.height)
maxSize.height=size.height;
return this;
}
}
make sure you design something more efficient then this...
Update:
and there is no need for the pack()!
Adam.
JComboBox has setPrototypeDisplayValue(Object) method that is used to calculate component's preferred width based on the length of the parameter. Try that.
And instead of pack() use doLayout() together with some revalidate() or repaint()
Do a pack() on the frame
To resize the combo box you can try:
comboBox.setModel( comboBox.getModel() );
I believe this should cause the preferred size of the combo box to be recalculated. Of course you would then need to do the pack() again.
Edit:
Added a simple SSCCE that shows this works:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ComboBoxTest3 extends JFrame implements ActionListener
{
JComboBox comboBox;
JTextField textField;
public ComboBoxTest3()
{
String[] tabs = {"one", "two", "three", "four", "five", "six", "seven" };
DefaultComboBoxModel model = new DefaultComboBoxModel(tabs);
comboBox = new JComboBox( model );
textField = new JTextField("hello");
add(comboBox, BorderLayout.WEST );
add(textField, BorderLayout.EAST );
JButton button = new JButton("Pack");
button.addActionListener( this );
add(button, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e)
{
textField.setText("hello there!");
comboBox.addItem("some longer text");
comboBox.setModel( comboBox.getModel() );
pack();
}
public static void main(String[] args)
{
JFrame frame = new ComboBoxTest3();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
Related
I'm trying to make a kitchen display system using a FlowLayout and I'm trying to figure out a way to add another panel on the 2nd row when the first row is already full. The width of the GUI will change according to user preference. When wider, it should show more of the components per row.
Approach - Variable width with WrapLayout
The GridLayout solution presumes the GUI requires 6 components per row.
For as many cols as needed to fill the width, & then show the components in as many rows as required, look to WrapLayout.
Approach - Variable width with JList
A JList can also be used here, since it seems all the components consist of a single (GUI) object.
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.*;
public class ListComponents {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
String[] listData = {
"Component 1", "Component 2", "Component 3",};
final DefaultListModel<String> model
= new DefaultListModel<String>();
for (String datum : listData) {
model.addElement(datum);
}
JList list = new JList(model);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.setVisibleRowCount(-1);
list.setCellRenderer(new ObjectCellRenderer());
Action addAction = new AbstractAction("Add New") {
#Override
public void actionPerformed(ActionEvent e) {
model.addElement("New Component");
}
};
JButton addNew = new JButton(addAction);
JPanel ui = new JPanel(new BorderLayout(3, 3));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new JScrollPane(list), BorderLayout.CENTER);
ui.add(addNew, BorderLayout.PAGE_START);
JFrame f = new JFrame("Component List");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(ui);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
class ObjectCellRenderer extends DefaultListCellRenderer {
Border border = new EmptyBorder(20, 5, 20, 5);
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
label.setBorder(border);
return label;
}
}
Approach - Fixed width with GridLayout
Using a GridLayout, when we know we always want a fixed number per row, regardless of width.
JPanel mainPanel = new JPanel(new GridLayout(0,6));
See new GridLayout(rows,cols):
Creates a grid layout with the specified number of rows and columns. All components in the layout are given equal size.
One, but not both, of rows and cols can be zero, which means that any number of objects can be placed in a row or in a column.
See this code for an example using a GridLayout(0,2) for the labels beneath Add Another Label
You can use a FlowLayout. From the tutorial How to Use FlowLayout:
The FlowLayout class puts components in a row, sized at their preferred size. If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows. If the container is wider than necessary for a row of components, the row is, by default, centered horizontally within the container.
EDIT If you want your layout to scroll vertically when there are too many rows, you can use a JScrollPane with horizontal scrolling disabled. You can do that with:
js.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
(where js is the JScrollPane that contains your FlowLayout panel).
EDIT 2 Well, the above isn't enough. You also need to set a viewport view on the JScrollPane that will track the JScrollPane width. Here's a class that does this (taken from here):
static class MyPanel extends JPanel implements Scrollable{
#Override
public Dimension getPreferredScrollableViewportSize() {
return this.getPreferredSize();
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 50;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
return 80;
}
/*
* (non-Javadoc)
* #see javax.swing.Scrollable#getScrollableTracksViewportWidth()
*/
#Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
#Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
You would use this by adding your current FlowLayout layout to an instance of MyPanel (instead of directly to the JScrollPane) and then calling
js.setViewportView(myPanelInstance);
I am working on the functionality of adding JCheckBox to Panel and then adding that Panel to JScrollPane. So far i am done with adding different JCheckBox dynamically to Panel but when i add that same Panel to JScrollPane, it does not shows the JCheckBoxes to JScrollPane
Q.1 What might be the possible reason for same thing not appearing in JScrollPane?
Q.2 Even if i added JCheckBox to Panel and then adding that Panel to JScrollPane how do i manage there setSelected functionality i mean how i can add the ActionListener to that dynamically added JCheckBox?
Note: I am using a AbsoluteLayout for Panel
Use for example GridLayout (1 column and multiple rows).
Keep array (or list) of the checkboxes. Go through the list adding ActionListener or you can get the main panel's children components, iterate through them casting to JCheckBox and add the listener.
The worst way is to define preferred size for the panel with AbsoluteLayout.
AbsoluteLayout is not a good solution but with fixed size it should work.
Are you calling revalidate on your panel object after you added checkbox?
As for Q2 you can store added checkboxes in a Vector or HashMap ( depends what logic is involved ) and then you can create custom ActionListener that implements mentioned interface.
What is more that you can pass reference of your panel to your custom ActionListener and within it's actionPerformed use that reference to call methods on the panel which stores vector of your checkboxes.
Here is my quick example of what I am talking about:
package pkg;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
class AddCheckBoxAction implements ActionListener{
CheckBoxPanel panel;
public AddCheckBoxAction(CheckBoxPanel panel){
this.panel = panel;
}
#Override
public void actionPerformed(ActionEvent arg0) {
panel.addNewCheckBox();
}
}
class CheckBoxAction implements ActionListener{
private int id;
CheckBoxAction(int id){
this.id = id;
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("CheckBox "+this.id+" was clicked");
}
}
class CheckBoxPanel extends JPanel{
private JButton addCheckBox = new JButton("Add CheckBox");
private Vector<JCheckBox> checkBoxes = new Vector<JCheckBox>();
public CheckBoxPanel(){
addCheckBox.addActionListener(new AddCheckBoxAction( this ) );
add(addCheckBox);
}
public void addNewCheckBox() {
JCheckBox chBox = new JCheckBox("CheckBox "+( this.checkBoxes.size()+1 ));
chBox.addActionListener(new CheckBoxAction(this.checkBoxes.size()+1));
this.checkBoxes.add(chBox);
add(chBox);
this.revalidate();
}
}
public class DynamicCheckBoxTest {
/**
* #param args
*/
public static void main(String[] args) {
CheckBoxPanel chD = new CheckBoxPanel();
JFrame mainFrame = new JFrame();
JScrollPane scrollP = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS );
scrollP.setViewportView(chD);
mainFrame.setSize(320,200);
mainFrame.getContentPane().add(scrollP);
mainFrame.setVisible(true);
}
}
AbsoluteLayout is not a healthy option,
Instead, you can use - Containers
I was able to fix your issue with that.
Below is the code, do refer it
Container contentPane = getContentPane();
contentPane = getContentPane();
JPanel panel = new JPanel();
List<String> configList = new ArrayList<>();
for( int i = 0; i < configList.size(); i++ )
{
String configValues = configList.get( i );
JCheckBox value = new JCheckBox( configValues );
panel.add( value );
}
JScrollPane scrollPane = new JScrollPane( panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
scrollPane.setPreferredSize( new Dimension( *SIZE*, *SIZE*) );
add( scrollPane );
contentPane.add( scrollPane, BorderLayout.CENTER );
A JLabel containing HTML-text automatically wraps lines using the available space. If one adds that JLabel to a JSrollPane he has to set the preferredSize to a decent value otherwise it won`t wrap. All this should work fine along other Components inside a JPanel using a LayoutManager.
Cause I want a resizeable application window I extended JScrollPane to keep track of the resize events and dynamically change the size synced to the width of the viewport. Basically it works but sometimes the calculation of the preferred height by the layout manager is wrong (value too big or too small). For instance the visibility of the red border cutting through the first line indicates that the calculation of the height is wrong.
I cannot reproduce the failure with a single wrapping JLabel.
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class WrappedLabel implements Runnable {
public static void main( String[] args ){
SwingUtilities.invokeLater( new WrappedLabel() );
}
#Override
public void run(){
final JPanel panel = new JPanel( new GridBagLayout() );
final GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 1.0;
gc.weighty = 1.0;
{
gc.gridx = 0;
gc.gridy = 0;
final JLabel label = new JLabel(
"<html>" + "please add some more text here"
);
label.setBorder( BorderFactory.createLineBorder( Color.RED ) );
panel.add( label, gc );
}
{
gc.gridx = 0;
gc.gridy = 1;
final JLabel label = new JLabel(
"<html>" + "please add some more text here"
);
label.setBorder( BorderFactory.createLineBorder( Color.RED ) );
panel.add( label, gc );
}
final JFrame frame = new JFrame();
frame.add( new ScrollPane( panel ) );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setSize( 256, 256 );
frame.setVisible( true );
}
private class ScrollPane extends JScrollPane implements ComponentListener {
ScrollPane( Container view ){
super( view );
this.viewport.addComponentListener( this );
}
#Override
public void componentHidden( ComponentEvent ce ){
}
#Override
public void componentMoved( ComponentEvent ce ){
}
/** calculating required height is a 3 step process
* 1. sync width of client and viewport, set height of client to high value
* 2. let GridbagManager calculate required minimum size
* 3. set preferredSize and revalidate
**/
#Override
public void componentResized( ComponentEvent ce ){
assert( this.viewport == ce.getSource() );
final Container view = (Container) this.viewport.getView();
final int width = this.viewport.getExtentSize().width;
view.setPreferredSize( new Dimension( width, Integer.MAX_VALUE ) );
final int height = view.getLayout().preferredLayoutSize( view ).height;
view.setPreferredSize( new Dimension( width, height ) );
view.revalidate();
}
#Override
public void componentShown( ComponentEvent ce ){
}
}
}
Apparently it's either a bug in GridBagLayout, or you are using the layout engine in a way totally unexpected by the developers. Several multi-line Labels with HTML inside, setting preferred size and immediately asking preferred size by the back door? Ugh!
I noticed that sometimes the layout works incorrectly when decreasing the window size: the panel inside scrollpane doesn't decrease and the horizontal scrollbar appears. (I am using Windows by the way).
Also, sometimes, if the vertical scrollbar was visible and the panel height was large, and then I increase the window size, the panel height remains unreasonably large and gaps appear around the label:
For me, the layout is wrong every other time when I decrease the window; increasing works better but if it goes wrong, it's also incorrect every other time. I tried debugging and printing values to console; it seems that view.getLayout().preferredLayoutSize( view ) depends not only on view.setPreferredSize but also on the current size of the panel and scrollpane. The code of GridBagLayout is too complicated to dive into.
DIRTY HACK
Since every other resize yields the correct result, why not resize it twice? Duplicating things in the ScrollPane.componentResized handler was unsuccessful, probably because the ScrollPane's size remains the same. The ScrollPane itself needs to be resized twice, with different values. To test it in the simplest way, I subclassed JFrame: it listens to componentResized and resizes its child window twice. The second resize has to be deferred via SwingUtilities.invokeLater.
Replace the lines
final JFrame frame = new JFrame();
frame.add( scroll );
by
final MyFrame frame = new MyFrame(scroll);
and add the following class:
private class MyFrame extends JFrame implements ComponentListener {
private Component child;
public MyFrame(Component child){
this.child=child;
setLayout(null);
getContentPane().add(child);
addComponentListener(this);
}
public void componentResized(ComponentEvent e) {
Dimension size=getContentPane().getSize();
child.setSize(new Dimension(size.width-1,size.height));
validate();
SwingUtilities.invokeLater(new ResizeRunner(size));
}
public void componentMoved(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
private class ResizeRunner implements Runnable {
private Dimension size;
public ResizeRunner(Dimension size){
this.size=size;
}
public void run() {
child.setSize(size);
validate();
}
}
}
The same can be achieved by subclassing a layout manager.
Obviously, this approach is inelegant and inefficient, but as a workaround for a JRE bug, and if nothing else helps... ;-)
I'm using a custom BasicComboBoxRenderer for a JComboBox and I've changed the appearance of the items of the drop-down list. However these changes also apply to the single top item that shows in the combobox (don't know how to call it).
I want the top item to be independent of the other items in the list, if possible. I would also like to get rid of the top item's blue color when it is focused (setFocusable(false) is not what I want).
I've tried to use the "renderer index" (-1) to affect the top item but it doesn't seem to help.
Any ideas?
P.S Unfortunately I couldn't add images to be more clear (no reputation).
EDIT: When I say that I want the top item to be independent from all the other items of the drop-down list I mean to always look different from the rest of them. For example in my custom BasicComboBoxRenderer I've set the selected item to have a different background, but this background also applies to the top item (since the selected item becomes the top item of the combobox).
EDIT 2: top item = I meant the combobox display area, so I want to affect the item that is shown at the display area and not the first item in the drop-down list. I managed to do this by using setBackground on the combobox itself AND setFocusable(false) (which is not very helpful because I want to keep the focus mechanism). But the problem is (except the focus issue) that if for example I set a border on each item in the list through a custom BasicComboBoxRenderer or ListCellRenderer class, this same border appears on the item that is shown in the display area. So there are 2 questions here:
--Is there any way to differentiate the layout of the items in the drop-down list and the single item in the display area?
--Is there any way to disable the focus color of the combobox without disabling the focus mechanism, just like when we use setFocusPainted(false) on buttons? (I've also tried to add a custom FocusListener on the combobox but any change made of the background through focusGained() affects only the button and not the item shown in the display area).
Sorry for the confusion and the multiple edits...
have look at Combo Box Prompt by #camickr,
defined prompt can't returns any value from JComboBox.getSelectedXxx
EDIT
BasicComboBoxRenderer or ListCellRenderer can do that this way
import java.awt.*;
import javax.swing.*;
public class TestHighLightRow {
public void makeUI() {
Object[] data = {"One", "Two", "Three"};
JComboBox comboBox = new JComboBox(data);
comboBox.setPreferredSize(comboBox.getPreferredSize());
comboBox.setRenderer(new HighLightRowRenderer(comboBox.getRenderer()));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(comboBox);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestHighLightRow().makeUI();
}
});
}
public class HighLightRowRenderer implements ListCellRenderer {
private final ListCellRenderer delegate;
private int height = -1;
public HighLightRowRenderer(ListCellRenderer delegate) {
this.delegate = delegate;
}
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component component = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
Dimension size = component.getPreferredSize();
if (index == 0) {
component.setBackground(Color.red);
if (component instanceof JLabel) {
((JLabel) component).setHorizontalTextPosition(JLabel.CENTER);
}
}
return component;
}
}
}
EDIT2
JComboBox has two states
editable
non_editable
basically all values could be accesible from UIManager, shortcuts
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;
public class MyComboBox {
private Vector<String> listSomeString = new Vector<String>();
private JComboBox someComboBox = new JComboBox(listSomeString);
private JComboBox editableComboBox = new JComboBox(listSomeString);
private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
private JFrame frame;
public MyComboBox() {
listSomeString.add("-");
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
//
someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
someComboBox.setEditable(true);
someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
//
editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
editableComboBox.setEditable(true);
JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
text.setBackground(Color.YELLOW);
JComboBox coloredArrowsCombo = editableComboBox;
Component[] comp = coloredArrowsCombo.getComponents();
for (int i = 0; i < comp.length; i++) {
if (comp[i] instanceof MetalComboBoxButton) {
MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
coloredArrowsButton.setBackground(null);
break;
}
}
//
non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
//
frame = new JFrame();
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(someComboBox);
frame.add(editableComboBox);
frame.add(non_EditableComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyComboBox aCTF = new MyComboBox();
}
});
}
}
I need some advice on which Swing Components to choose in order to achieve the following:
I have something like a "table" structure, that every time that I click the "Add" button, another "row" should be inserted on the "table". Each row is composed of 2 JTextField. The problem I am having with the GridLayout (the layout used in the pictures below) is that if I add another row, then the heights of the text fields will be shortened and I don't want that (picture on the right), I want to preserve the same height for every row.
What I would like to happen is to have the extra row appear below the last one, so that I could use the JScrollPane and scroll to see it.
Should I use another layout rather than the GridLayout? Maybe the AbsoluteLayout or even using the Table Component?
Thanks.
I would use a JTable and set the row height to whatever you desire. For example:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class TableEg {
private static final int ROW_HEIGHT = 40;
private static final String[] TABLE_COLUMNS = {"Foo", "Bar"};
private static void createAndShowGui() {
final DefaultTableModel tableModel = new DefaultTableModel(TABLE_COLUMNS, 2);
JTable table = new JTable(tableModel );
table.setRowHeight(ROW_HEIGHT);
JScrollPane scrollpane = new JScrollPane(table);
JButton addRowBtn = new JButton(new AbstractAction("Add Row") {
#Override
public void actionPerformed(ActionEvent arg0) {
tableModel.addRow(new String[]{"", ""});
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(addRowBtn);
JFrame frame = new JFrame("TableEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollpane, BorderLayout.CENTER);
frame.getContentPane().add(btnPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Let's say that you add your JTextField in a Jpanel, and you Jpanel in a JScrollPane. Now you would set a preferredSize for you JScrollPane (since you want a fixed displayable area), but you modify the height of the JPanel dinamically based in the amount of JTextField you are placing at that time.
In other words, if you have 2 JTextField in a Jpanel set with GridLayout of 2 columns; you JTextField would take the entire height of the Jpanel; but if you include 2 more they would have to make room for this two and therefore shortening.
Notice that you have 2 rows in a JPanel set to "100" height each row would use "50". if you add another row but also modify the height of the JPanel to "150" each JTextField would still take "50" pixels.
I am a newbie, and it is a possibility that i am not 100% right; if that it is the case "Sorry". I just wanted help.
Try this....
JScrollPane scroll = new JScrollPane(Your_Table);
This will make your table to scroll....