Resize table in miglayou - java

I have created a MigLayout, which looks like that:
As you can see the table does not resize correctly.
I am creating my layout like that:
public JScrollPane createLayout() {
JPanel panel = new JPanel(new MigLayout("debug 400"));
JScrollPane sp;
JLabel lab = new JLabel(labelValue);
lab.setFont(new Font("Tahoma", Font.BOLD, 15));
panel.add(lab, "wrap");
panel.add(resultsTable(), "growx, wrap");
panel.add(resultsButtons(), "wrap");
//set table properties
tableProperties(resultTable);
updateResultsTable();
sp = new JScrollPane(panel);
sp.repaint();
sp.validate();
return sp;
}
My table is created like that:
private JPanel resultsTable() {
JPanel panel = new JPanel(new MigLayout(""));
JScrollPane scrollTablePane;
rtm = new ResultTableModel(resultList);
resultTable = new JTable(rtm);
scrollTablePane = new JScrollPane(resultTable);
sorter = new TableRowSorter<TableModel>(resultTable.getModel());
resultTable.setRowSorter(sorter);
scrollTablePane.repaint();
scrollTablePane.validate();
//add to panel
panel.add(scrollTablePane);
panel.repaint();
panel.validate();
return panel;
}
Furthermore, I set the table properties in the following method:
public void tableProperties(JTable table) {
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
Any recommendations why my columns of my table do not stretch?
I appreciate your answer!

If you want your table to be auto resizable try to use inside createLayout method the following constructor JPanel panel = new JPanel(new MigLayout("debug 400,wrap 1","[grow,fill]","[grow,fill]")) and inside resultsTable method the following constructor JPanel panel = new JPanel(new MigLayout("","[grow,fill]","[grow,fill]"))

Related

Align JTextArea in JPanel

I'm currently building GUI with Java Swing.
My current code produces this.
The JTextArea of Product List makes the GUI looks awkward, how can I make the JTextArea looks like this, where it seems to have an extra row:
The GroupLayout code I'm using is:
gr.setVerticalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(productName).addComponent(productText).addComponent(productList))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(amount).addComponent(amountText).addComponent(prodScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(description).addComponent(desScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(addButton).addComponent(remButton)));
gr.setHorizontalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(productName).addComponent(amount).addComponent(description).addComponent(addButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productText).addComponent(amountText).addComponent(desScroll).addComponent(remButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productList).addComponent(prodScroll)));
I think the minority of people would choose to use GridBagLayout. However, I dislike it (among with GroupLayout) since it is "hard to use". I use nested panels instead with various Layout Managers. Using only BorderLayout and GridLayout you can achieve something like the following example, which is totally resizable, giving emphasis to "interaction" components (I mean, there is no reason to resize a constant-texted JLabel, right?)
I did not add any comments in purpose, so you can experiment with constants (and layout constraints) and see their reason of existence while having the documentations opened.
Code:
public class NestedLayoutManagersExample extends JFrame {
private static final long serialVersionUID = -7042997375941726246L;
private static final int labelsWidth = 80;
private static final int textFieldColumns = 15;
private static final int spaceBetweenAllComponents = 10;
public NestedLayoutManagersExample() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel contentPane = new JPanel(new GridLayout(1, 2, 50, 50));
contentPane.setBorder(BorderFactory.createEmptyBorder(spaceBetweenAllComponents, spaceBetweenAllComponents,
spaceBetweenAllComponents, spaceBetweenAllComponents));
setContentPane(contentPane);
add(createLeftPanel());
add(createRightPanel());
setLocationByPlatform(true);
pack();
}
private Component createRightPanel() {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel productListLabel = new JLabel("Product list");
mainPanel.add(productListLabel, BorderLayout.PAGE_START);
JList<String> productList = new JList<>();
DefaultListModel<String> listModel = new DefaultListModel<>();
Arrays.asList("Small Chair", "Big Chair", "Flying Chair").forEach(listModel::addElement);
productList.setModel(listModel);
JScrollPane listScrollPane = new JScrollPane(productList);
mainPanel.add(listScrollPane, BorderLayout.CENTER);
return mainPanel;
}
private Component createLeftPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JPanel topPanel = new JPanel(new GridLayout(2, 1, spaceBetweenAllComponents, spaceBetweenAllComponents));
topPanel.add(createStraightPanel("Product Name"));
topPanel.add(createStraightPanel("Amount"));
mainPanel.add(topPanel, BorderLayout.PAGE_START);
JPanel centerPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';> Description");
label.setVerticalAlignment(JLabel.TOP);
centerPanel.add(label, BorderLayout.LINE_START);
centerPanel.add(createTextAreaPanel());
mainPanel.add(centerPanel, BorderLayout.CENTER);
return mainPanel;
}
private JPanel createTextAreaPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JTextArea textArea = new JTextArea(1, textFieldColumns);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
mainPanel.add(textAreaScrollPane, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new BorderLayout());
JButton addButton = new JButton("Add");
buttonsPanel.add(addButton, BorderLayout.LINE_START);
JButton removeButton = new JButton("Remove");
buttonsPanel.add(removeButton, BorderLayout.LINE_END);
mainPanel.add(buttonsPanel, BorderLayout.PAGE_END);
return mainPanel;
}
private Component createStraightPanel(String labelText) {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';>" + labelText);
mainPanel.add(label, BorderLayout.LINE_START);
JTextField textField = new JTextField(textFieldColumns);
mainPanel.add(textField, BorderLayout.CENTER);
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new NestedLayoutManagersExample().setVisible(true));
}
}
Preview:

BorderLayout and JScrollPane problems

I have a JFrame with three areas:
A scrollpane with a list of objects
A panel with labels and textfields
A scrollpane with a panel potentially having multiple labels
When you click the item on the list, the textfields on the panel are filled and the labels on the second scroll are created. I have two problems with my code:
For some reason the scrollpane at the botom of the screen does not fill the whole borderlayout's south area, only half of it.
the scrollpane does not show anything when the item on the list is selected.
Here I tried to make an example:
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
JPanel geral = new JPanel();
JPanel lista = new JPanel();
JPanel dados = new JPanel();
JPanel paneHist = new JPanel();
JPanel historico = new JPanel();
GridLayout gridLay = new GridLayout(0, 2, 5, 10);
geral.setLayout(gridLay);
dados.setLayout(gridLay);
historico.setLayout(new BorderLayout());
lista.setLayout(new BorderLayout());
paneHist.setLayout(gridLay);
this.setLayout(new BorderLayout());
this.add(geral);
geral.add(lista, BorderLayout.WEST);
geral.add(dados, BorderLayout.EAST);
geral.add(historico, BorderLayout.SOUTH);
DefaultListModel listModel = new DefaultListModel();
listModel.addElement("just testing");
final JList list = new JList(listModel);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisible(true);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scroll = new JScrollPane(list);
scroll.setPreferredSize(new Dimension(100, 500));
lista.add(scroll, BorderLayout.CENTER);
JTextField jtf = new JTextField();
dados.add(new JLabel("test:"));
dados.add(jtf);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent lse) {
jtf.setText("clicked");
paneHist.add(new JLabel("texttexttext"));
paneHist.add(new JLabel("texttexttext"));
}}
);
JScrollPane scrollHist = new JScrollPane(paneHist);
scrollHist.setPreferredSize(new Dimension(500, 100));
historico.add(new JLabel("Historico:"), BorderLayout.NORTH);
historico.add(scrollHist, BorderLayout.EAST);
//list.setCellRenderer(new CellRenderer());
this.validate();
this.repaint();
}
Can't really tell what you are doing from the posted code.
Some general comments:
Don't use setPreferredSize(). Let each component determined its preferred size. In the case of a JList you can use the setVisibleRowCount(...) method so the JList can calculate a reasonable size.
In your ListSelectionListener, when you add/remove components from a visible GUI you need to revalidate() and repaint() the panel.

Increase a row size in Gridlayout

The above frame contains gridlayout with two rows. First row is text area,second is a panel with two checkboxes. I want to increase height of first row so that first row should be 75% of Total height and second row should be 25%. How can I do that? Here is my code snippet:
setLayout(new GridLayout(2, 0, 0, 0));
Panel text_panel = new Panel();
add(text_panel);
text_panel.setLayout(new GridLayout(1, 0, 0, 0));
JTextArea textArea = new JTextArea();
textArea.setText("text to be displayed");
JScrollPane scroll = new JScrollPane (textArea);
text_panel.add(scroll);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
Border border = BorderFactory.createLineBorder(Color.GRAY);
textArea.setBorder(border);
textArea.setFont(new Font("Arial",Font.PLAIN,12));
textArea.setCaretPosition(0);
textArea.requestFocus();
Panel checebox_panel = new Panel();
checebox_panel.setBackground(Color.WHITE);
add(checebox_panel);
checebox_panel.setLayout(new GridLayout(1, 0, 0, 0));
androidCheckBox = new JCheckBox("Open start page");
androidCheckBox.setBackground(Color.WHITE);
androidCheckBox.addItemListener(itemListener);
androidCheckBox.setSelected(true);
checebox_panel.add(androidCheckBox);
eclipseCheckBox = new JCheckBox("register for updates");
eclipseCheckBox.setBackground(Color.WHITE);
eclipseCheckBox.addItemListener(itemListener);
eclipseCheckBox.setSelected(true);
checebox_panel.add(eclipseCheckBox);
This is not possible with GridLayout. GridLayout will always use even spacing. Look into another layout manager.
Here is a good reference:
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
With GridLayout you can't have two rows that are different sizes. Look into BoxLayout. Something like this:
JPanel content = new JPanel();
frame.getContentPane().add(content);
LayoutManager layout = new BoxLayout(content, BoxLayout.Y_AXIS);
Box boxes[] = new Box[2];
boxes[0] = Box.createHorizontalBox();
boxes[1] = Box.createHorizontalBox();
boxes[0].createGlue();
boxes[1].createGlue();
content.add(boxes[0]);
content.add(boxes[1]);
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
panel.setPreferredSize(new Dimension(500,300));
panel2.setPreferredSize(new Dimension(500,200));
boxes[0].add(panel);
boxes[1].add(panel2);
Using setPreferredSize is never optimal, but it works. This is just an example of how you could do it, I'm sure there is better ways though! ;)
"Increase a row size in Gridlayout" I came across this requirement and by trying to device a solution I got one, tried border instead grid layout. it might be helpful :)
here is the code:
import ComponentMeta.RequiredComp;
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PromptPopup extends JDialog {
private final JScrollPane scrollPane = new JScrollPane();
private int rows;
private int cols;
private int vGap;
private int hGap;
private Map<String, Component> componentRepo;
public PromptPopup(JFrame parent) {
super(parent);
componentRepo = new HashMap<>();
this.setModalityType(ModalityType.APPLICATION_MODAL);
}
public void setComponentsDisplayStyle(int rows, int cols, int vGap, int hGap) {
this.rows = rows;
this.cols = cols;
this.vGap = vGap;
this.hGap = hGap;
}
public void setComponentReop() {
JTextField dynamicParamTextField = new JTextField();
this.componentRepo.put("COMPANY_CODE", dynamicParamTextField);
JTextField dynamicParamTextField2 = new JTextField();
this.componentRepo.put("DIST_CODE", dynamicParamTextField2);
JTextField dynamicParamTextField3 = new JTextField();
this.componentRepo.put("LOCA_CODE", dynamicParamTextField3);
JTextField dynamicParamTextField4 = new JTextField();
this.componentRepo.put("TOKEN_EXEC", dynamicParamTextField4);
}
public void initPopupUI() {
//Setting content panes layout
getContentPane().setLayout(new BorderLayout(0, 0));
//Creating a root panel(root container) to hold the child components
JPanel rootContainer = new JPanel();
rootContainer.setLayout(new BorderLayout());
//Creating header panel(header container) to hold the header components
JPanel header = new JPanel();
header.setLayout(new FlowLayout());
JLabel headerText = new JLabel("Source query parameters required ");
headerText.setForeground(Color.WHITE);
header.add(headerText);
header.setBackground(Color.BLUE);
//Creating footer panel(footer container ) to hold the footer components
JPanel footer = new JPanel();
footer.setLayout(new FlowLayout());
JButton executeWithParamsButton = new JButton("Execute with params");
executeWithParamsButton.setBackground(Color.BLACK);
executeWithParamsButton.setForeground(Color.WHITE);
JButton cancelButton = new JButton("Cancel");
cancelButton.setBackground(Color.RED);
cancelButton.setForeground(Color.WHITE);
footer.add(executeWithParamsButton);
footer.add(cancelButton);
footer.setBackground(Color.BLUE);
//Creating content panel(content container) to hold the all dynamically generated components
JPanel contentContainer = new JPanel();
GridLayout gridLayout = new GridLayout(this.rows, this.cols, this.hGap, this.vGap);
contentContainer.setLayout(gridLayout);
for (Map.Entry entry : componentRepo.entrySet()) {
JLabel dynamicParamLabel = new JLabel(entry.getKey().toString());
contentContainer.add(dynamicParamLabel);
contentContainer.add((Component) entry.getValue());
}
// Adding all the created containers to the root container one by one
rootContainer.add(header, BorderLayout.NORTH);
rootContainer.add(contentContainer, BorderLayout.CENTER);
rootContainer.add(footer, BorderLayout.SOUTH);
//Adding the root container to the scroll pane in order the view to be scrollable nno matter how many components are there.
scrollPane.setViewportView(rootContainer);
getContentPane().add(scrollPane);
}
}
And Here is output I wanted i.e The Header to be on top consuming space only based on it's components and same for the Center panel and The footer containing button controls.
output

JTextArea with same parameters but not same size

public UserInterface(){
super(new BorderLayout());
fc = new JFileChooser();
setComponents();
}
public void setComponents(){
//top section
openButton = new JButton("Charger fichier");
openButton.addActionListener(this);
JPanel buttonPanel = new JPanel();
buttonPanel.add(openButton);
//left section
//class panel
JPanel classe = new JPanel();
classes = new JTextArea(25,15);
classes.setMargin(new Insets(5,5,5,5));
classes.setEditable(false);
JScrollPane classeScrollPane = new JScrollPane(classes);
classe.setBorder(new TitledBorder("Classes"));
classe.add(classeScrollPane);
//right section
JPanel right = new JPanel(new BorderLayout());
JPanel right_top = new JPanel(new GridLayout(2,2));
//attribut panel
JPanel attribut = new JPanel();
attributs = new JTextArea(8,19);
attributs.setMargin(new Insets(5,5,5,5));
attributs.setEditable(false);
JScrollPane attributScrollPane = new JScrollPane(attributs);
attribut.setBorder(new TitledBorder("Attributs"));
attribut.add(attributScrollPane);
//function panel
JPanel methode = new JPanel();
methodes = new JTextArea(8,19);
methodes.setMargin(new Insets(5,5,5,5));
methodes.setEditable(false);
JScrollPane methodeScrollPane = new JScrollPane(methodes);
methode.setBorder(new TitledBorder("Methodes"));
methode.add(methodeScrollPane);
//subclass panel
JPanel sousclasse = new JPanel();
sousclasses = new JTextArea(8,19);
methodes.setMargin(new Insets(5,5,5,5));
methodes.setEditable(false);
JScrollPane sousclasseScrollPane = new JScrollPane(sousclasses);
sousclasse.setBorder(new TitledBorder("Sous-classes"));
sousclasse.add(sousclasseScrollPane);
//relation panel
JPanel relation = new JPanel();
relations = new JTextArea(8,19);
relations.setMargin(new Insets(5,5,5,5));
relations.setEditable(false);
JScrollPane relationScrollPane = new JScrollPane(relations);
relation.setBorder(new TitledBorder("Relations"));
relation.add(relationScrollPane);
right_top.add(attribut);
right_top.add(methode);
right_top.add(sousclasse);
right_top.add(relation);
//detail panel
JPanel detail = new JPanel();
details = new JTextArea(5,40);
details.setMargin(new Insets(5,5,5,5));
details.setEditable(false);
JScrollPane detailScrollPane = new JScrollPane(details);
detail.setBorder(new TitledBorder("Détails"));
detail.add(detailScrollPane);
right.add(right_top,BorderLayout.CENTER);
right.add(detail,BorderLayout.SOUTH);
add(buttonPanel, BorderLayout.NORTH);
add(classe, BorderLayout.WEST);
add(right, BorderLayout.CENTER);
}
the layout created from code above is:
You can see the text area of 'sousclass' panel is smaller than other JTextArea with the same parameters(8,19). Could anyone tell me why?
Also, assume that i have some data, I'd like to display class name in class section, once i click one of classes, it displays attributs of that class in the attribut section, how could i realize this function? Thanks。
JPanel sousclasse = new JPanel();
sousclasses = new JTextArea(8,19);
methodes.setMargin(new Insets(5,5,5,5)); // wrong variable
methodes.setEditable(false); // wrong variable
You didn't set the margin on the text area. You are using the wrong variable name.

How to activate ActionEvent inside JMenu to show new panel on the frame?(Basic)

I just started to learn swing by myself, I'm little bit confused why my event does not work here:
1.I'm trying to delete everything from my panel if the user click menu bar -> load but it force me to change the panel to final because i'm using it inside the event!
2.I have defined new panel in my event and defined two more container to add to that panel and then add it to the main frame but it seems nothing happening!
Please help me if you can find out what is wrong.
Sorry in advance for messy code.
I appreciate any hints.
public class SimpleBorder {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run()
{
myFrame frame = new myFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class MyFrame extends JFrame {
public MyFrame()
{
setSize(500,500);
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel label = new JLabel("my name is bernard...");
Color myColor = new Color(10, 150, 80);
panel.setBackground(myColor);
label.setFont(new Font("Serif", Font.PLAIN, 25));
Dimension size = label.getPreferredSize();
Insets insets = label.getInsets();
label.setBounds(85+insets.left, 120+insets.top , size.width, size.height);
panel.add(label);
JMenuBar menu = new JMenuBar();
setJMenuBar(menu);
JMenu col = new JMenu("Collection");
menu.add(col);
JMenu help = new JMenu("Help");
menu.add(help);
Action loadAction = new AbstractAction("Load")//menu item exit goes here
{
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event)
{
JTextArea text = new JTextArea(10, 40);
JScrollPane scrol1 = new JScrollPane(text);
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
JScrollPane scrol2 = new JScrollPane(list);
JPanel panel2 = new JPanel(new BorderLayout());
panel2 = new JPanel(new GridLayout(1, 2 ));
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
}
};
JMenuItem load = new JMenuItem(loadAction);
col.add(load);
add(panel);
}
}
Call revalidate()/repaint() on your JFrame instance after adding the new panel:
JPanel panel2 = new JPanel(new BorderLayout());
// panel2 = new JPanel(new GridLayout(1, 2 ));//why this it will overwrite the above layout
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
revalidate();
repaint();
Also call pack() on you JFrame instance so all components are spaced by the layoutmanager. As said in a comment dont extend the JFrame class, create a variable of the frame and initiate all that you need on the frames instance, and dont set a layout to null, unless you love hard work :P
Alternatively as mentioned by mKorbel, a CardLayout may be more what you want, it will allow you to use a single JPanel and switch between others/new ones:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";
//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
//add card panel to frame
frame.add(cards);
//swap cards
CardLayout cl = (CardLayout)(cards.getLayout());//get layout of cards from card panel
cl.show(cards, TEXTPANEL);//show another card

Categories

Resources