Jtable in BoxLayout - java

I have a BoxLayout (in a panel of a BorderLayout) in which I've put a JTable and a button vertically. I would like the table to have a fixed width and that the height should resize itself up to filling the panel. At the moment, I'm fine with the displayed width but not that it's filling up the whole panel height. For example, if there are zero data in the table, I would like only the column names to be shown. I've tried things like setViewportView() and setPreferredSize(), but can't really make it work. Any suggestions? Is it in the layout or scrollpane?
String[] columnNames = { "Date", "Type"
};
Object[][] data = {
};
JTable myTable = new JTable(data, columnNames);
JButton okButton = new JButton("OK");
JPanel panWest = new JPanel();
panWest.setLayout(new BoxLayout(panWest, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(myTable);
panWest.add(scrollPane);
panWest.add(okButton);
EDIT
This is what ended up working:
Dimension dimension = new Dimension();
dimension.height = (myTable.getRowCount()*myTable.getRowHeight())+
myTable.getTableHeader().getPreferredSize().height;
dimension.width = myTable.getColumnModel().getTotalColumnWidth();
scrollPane.setMaximumSize(dimension);

I would like the table to have a fixed width and that the height
should resize itself up to filling the panel.
and
I have a BoxLayout (in a panel of a BorderLayout) in which I've put a
JTable and a button vertically.
there are three (mentioned only simple) ways
use built_in LayoutManager for JPanel - FlowLayout (FLowLayout.CENTER),
override FLowLayout.LEFT or RIGHT in the case that you want to aling,
JComponent laid by FlowLayout never will be resizable without programatically to change XxxSize and notified by revalidate & repaint,
set proper size for JScrollPane by override JTable.setPreferredScrollableViewportSize(new Dimension(int, int));,
JScrollPane accepts this Dimension as initial size, required is usage of JFrame.pack(), before JFrame.setVisible(true)
BoxLayout accepts min, max and preferred size, override all these three sizes for JScrollPane
(half solution, but most comfortable) change LayoutManager for JPanel to BorderLayout,
put JScrollPane with JTable to BorderLayout.EAST/WEST area,
then override JTable.setPreferredScrollableViewportSize(new Dimension(int, int));,
JScrollPane will occupy whole area for BorderLayout.EAST/WEST and will be resizeable only on heights coordinates
use MigLayout, here are a few posts about MigLayout and JScrollPane (with JTextArea, JTable)

Related

Swing JScrollPane resizing to fit the viewport panel

I tried a lot of layout managers but none could solve my problem:
I want the items in a scrollPane to keep their size (preferred or minimum) and not being resized (reduced) to fit the viewport Panel. Since if it is a JTextArea, and if the text area has blank space and it is bigger then the viewport, it would reduce it so the blank text area won't be shown. I want the blank text area to be shown for appearance issues.
Im stacking one item after another using BoxLayout, and it seems to me that for text areas the setMinimum method fails.
If the text area has blank space, then the scrollbar of the ScrollPane won't appear, instead it only appears it there are no blank space left.
Any solution?
JScrollPane materialPane = new FScrollPane();
this.materialPaneView = new TPanel();
this.materialPaneView.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/2)));
this.materialPaneView.setLayout(new BoxLayout(this.materialPaneView, BoxLayout.Y_AXIS));
materialPane.setViewportView(materialPaneView);
materialPane.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/2)));
for(Material mat: this.unit.getMaterial()){
this.addMaterial(mat);
}
centerPanel.add(sectionPane);
centerPanel.add(exercisePane);
centerPanel.add(materialPane);
this.add(upperPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
public void addMaterial(Material mat){
JTextField matName = new JTextField(30);
JPanel fieldButtonPanel = new TPanel();
fieldButtonPanel.setLayout(new GridLayout(1,2));
JPanel fieldPanel = new TPanel(new FlowLayout(FlowLayout.LEFT));
JPanel deleteMatButtonPanel = new TPanel(new FlowLayout(FlowLayout.RIGHT));
matName.setText(mat.getName());
matName.setMaximumSize(new Dimension(FFont.def.getSize()*20, 30));
fieldPanel.add(matName);
JButton deleteMat = new JButton("Delete Material");
deleteMatButtonPanel.add(deleteMat);
fieldButtonPanel.add(fieldPanel);
fieldButtonPanel.add(deleteMatButtonPanel);
fieldButtonPanel.setAlignmentX(LEFT_ALIGNMENT);
JTextArea matText = new FTextArea(mat.getDesc(), (int)(WIDTH*0.95), (int)(HEIGHT/3.4));
matText.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/3.5)));
/*matText.setMaximumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/3.4)));*/
matText.setText(mat.getDesc());
matText.setAlignmentX(LEFT_ALIGNMENT);
this.materialPaneView.add(fieldButtonPanel);
this.materialPaneView.add(matText);
matName.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
mat.setName(matName.getText());
}
});
HEIGHT and WIDTH are constants, and TPanel FScrollPane are my predefined transparent panels. The BoxLayout panel is the viewport of a scrollPane, and still, it would resize the text areas.
I am not sure i get what you are asking for so please tell me if i totally missed the point...
As far as i know the Viewport size is controlled by the component inside the JScrollPane and the JScrollPane size wont change no matter what happens to the viewport.
You either want to:
A) Resize the JScrollPane to the same size as it's content.
I would implement listeners to look for the content size change and resize the ScrollPane accordingly but you need to pay attention to resize the whole Hierarchy too.
B) You want to resize the viewport so that it fits in the JScrollPane? Y'know without scrollbars.
I had this problem and fixed it by using a ScrollablePanel component. Check this answer, follow the link to download the .class and use it to use a JPanel that resizes to fit the ScrollPane.
Those arent very detailed answers but i will need more information about what you are trying to do before expanding on it. And your code isnt complete, always share a code that we can CTRL+C/V and readily verify the problem in our end.

I want my JTable at the centre

I want my JTable at the centre of my JFrame and for this purpose i have used setbounds method but it's not doing anything and i don't want to use layout managers.I just want to know that why it's not doing anything?
Here is my code:
tabel=new JTable(data,columnNames);
tabel.setLayout(null);
tabel.setPreferredScrollableViewportSize(new Dimension(500,50));
tabel.setFillsViewportHeight(true);
JScrollPane pane=new JScrollPane(tabel);
pane.setBounds(100,700,200,200);
add(pane);
It's better to use layout managers but if you insist,that you want to move JTable in JFrame by setting layout to null,then you should try the following option:
(1)Make a JPanel in JFrame and add that table to JPanel in this way
JPanel panel=new JPanel();
panel.setBounds(20,300,700,300);
add(panel);
tabel=new JTable(data,columnNames);
tabel.setBounds(100,20,700,400);
tabel.setPreferredScrollableViewportSize(new Dimension(500,50));
tabel.setFillsViewportHeight(true);
JScrollPane pane=new JScrollPane(tabel);
panel.add(pane);
You should add everything to a JPanel, and then set the layout of the JPanel to a border layout. Add the table to the JPanel and then position it at the center. This is the easiest way to do it. Layouts may seem complicated and inconvenient at first but once you learn them, you quickly realise they are a million times easier that setting bounds and null layouts. Here is a link to learn about border layout: https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
You are adding JTable to a JFrame(Top level component).This may get you going
JPanel tablePanel = new JPanel(new GridBagLayout());
GridBagConstraints layout= new GridBagConstraints();
JTable jtable = new JTable();
jtable.setPreferredScrollableViewportSize(new Dimension(500,50));
jtable.setFillsViewportHeight(true);
layout.fill = GridBagConstraints.BOTH;
layout.weightx = 1;
layout.weighty = 1;
layout.gridx = 0;
layout.insets = new Insets(10,10,10,10);
tablePanel.add(new JScrollPane(jtable), layout)
You may want to set layout dimensions and insets according to your jtable.

How to fill Cells of GridbagLayout with the controls in Swing?

I need to design a swing GUI which has a JFrame with a Menu on top and another main panel having three more panels in center and a separate panel in the bottom of the panel. The required design of the UI is as below
But when I run my swing application I get the output like this (all the panels are packed in the center of the window)
Below is my code
import java.awt.*;
import javax.swing.*;
public class FrontEndView {
private JFrame mainFrame;
private JPanel mainPanel,subPanelUp,subPanelDown,panelLeft,panelRight,panelCenter,panelDown;
private JScrollPane scrollPane;
private JList logViewList;
private JPanel panel1;
public FrontEndView(){
this.prepareGUI();
}
public void prepareGUI(){
mainFrame=new JFrame("GUI");
Toolkit tk = Toolkit.getDefaultToolkit();
int xSize = ((int) tk.getScreenSize().getWidth());
int ySize = ((int) tk.getScreenSize().getHeight());
mainFrame.setSize(xSize,ySize);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(true);
mainFrame.setLayout(new BorderLayout());
mainPanel=new JPanel();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
GridBagConstraints gridbagConstMain = new GridBagConstraints();
GridBagConstraints gridbagConstSub = new GridBagConstraints();
subPanelUp=new JPanel();
subPanelUp.setLayout(new GridBagLayout());
subPanelUp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
panelLeft=new JPanel();
panelLeft.setBorder(BorderFactory.createTitledBorder("Message Defs"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelLeft, gridbagConstSub);
panelCenter=new JPanel();
panelCenter.setBorder(BorderFactory.createTitledBorder("Main Workspace"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 1;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelCenter, gridbagConstSub);
panelRight=new JPanel();
panelRight.setBorder(BorderFactory.createTitledBorder("Script Viewer"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 2;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelRight, gridbagConstSub);
mainPanel.add(subPanelUp,gridbagConstMain);
subPanelDown=new JPanel();
subPanelDown.setLayout(new BorderLayout());
panelDown=new JPanel();
panelDown.setBorder(BorderFactory.createTitledBorder("Log View"));
logViewList= new JList();
panelDown.add(logViewList);
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
//gridbagConst.ipady=20;
//gridbagConst.weightx = 0.0;
gridbagConstSub.gridwidth = 5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelDown.add(panelDown,BorderLayout.PAGE_END);
mainPanel.add(subPanelDown, gridbagConstSub);
scrollPane=new JScrollPane(mainPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
mainFrame.add(scrollPane);
mainFrame.setVisible(true);
}
public static void main(String[] args){
FrontEndView frontEnd = new FrontEndView();
}
}
I want to fill the GridBagLayout's cells with the relevant panel/control it holds as shown in the design and also each panel should have its controls filled inside (I need to add a JList inside the panelDown whose size should be the size of the panelDown JPanel).Simply I don't need any extra space visible in my JFrame. Please guide me on what is missing in my code.
I would suggest you can use nested panels with different layout managers to solve the problem.
The default layout of a frame is a BorderLayout.
So you could create a panel and add it to the PAGE_END so it displays the entire width at the bottom.
Then you can create another panel that uses a GridLayout. You can then add 3 child panels to this panel and each panel can use its own layout. Then you add this panel to the CENTER of the frame. As the frame size changes the extra spaces will be allocated to the CENTER so the panels will dynamically grow.
Edit:
Too many panels for me to take the time to understand what is happening
I was suggesting a structure like this:
frame (which by default uses a BorderLayout)
--- CENTER
panel using GrigBagLayout
childPanel1
childPanel2
childPanel3
---- PAGE_END
JScrollPane containing the JList
When you create the JList the basic code would be:
JList list = new JList(...);
list.setVisibleRowCount(5);
JScrollPane scrollPane = new JScrollPane( list );
There is no need to create a panel just to add the list to another panel. The point of setting the visible row count is to give the JList a fixed height. Scrollbars will then appear in the scroll pane as needed.
Now that the PAGE_END has a fixed height component all the reset of the space will go to the component that you add to the CENTER of the frame.
all the panels are packed in the center of the window)
The panels are displayed at their preferred sizes when you use the GridBagLayout. If the total size of all the panels is less than the size of the scrollpane then they will be in the center. If you want the panels to fill the space available, then I believe you need to use the weightx/y constraints. Read the section from the Swing tutorial on How to Use GridBagLayout which describes all the constraints.
That is why I suggested a GridLayout instead. It will make all the panels the same size and will fill the viewport of the scroll pane without playing with constraints.
mainFrame.add(menubar,BorderLayout.NORTH);
That is not how you add a menubar to the frame.
You should be using:
mainFrame.setJMenuBar(menuBar);
You were told this in your last question. Why did you not listen to the advice??? Why should we take the time to help when you don't pay attention to what is suggested.
Based on your instructions I changed my design in a way all of the outer panels are used with Border Layout and the inner most ones with more controls were used with Grid, GridBag and FlowLayouts based on the requirement. In that way the entire design could be done nicely.
Also if a particular panel within a cell of a layout needs to be expanded, I used the setPreferredSize(new Dimension(int,int)) whenever required.

Java - JScrollPane Doesn't align with JTable

I am trying to make a JTable that has a width of 500. The problem is that the JScrollPane associated with the table doesn't appear next to the table.
Here is the relevant code:
// Create authorsPanel
JPanel authorsPanel = new JPanel(new BorderLayout(5,5));
authorsPanel.setBorder( new TitledBorder("Author Selection") );
// Configure author table
DefaultTableModel authorstableModel = new DefaultTableModel(new String[80][1], new String[]{"Authors"}) {
#Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
JTable authorsTable = new JTable(authorstableModel);
authorsTable.getColumnModel().getColumn(0).setPreferredWidth(500);
authorsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
try {
authorsTable.setAutoCreateRowSorter(true);
} catch(Exception continuewithNoSort) {
}
JScrollPane tableScroll = new JScrollPane(authorsTable);
Dimension tablePreferred = tableScroll.getPreferredSize();
tableScroll.setPreferredSize(new Dimension(500, tablePreferred.height/3));
authorsPanel.add(tableScroll);
Here is a screenshot:
When I get rid of the line:
authorsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
Then the table returns to being the full width of the panel, so it seems like I need this line.
The java docs on BorderLayout states :
The components are laid out according to their preferred sizes and the
constraints of the container's size. The NORTH and SOUTH components
may be stretched horizontally; the EAST and WEST components may be
stretched vertically; the CENTER component may stretch both
horizontally and vertically to fill any space left over.
You have used authorsPanel.add(tableScroll) to add the JScrollPane to the JPanel. So you are basically adding it to the center. So this is going to occupy the whole space that is lying vacant.
The solution to your problem lies in choosing a different layout. I could suggest MigLayout which is very versatile and you can get all kinds of effects using it.
You add your scroll pane to a panel with BorderLayout. BorderLayout does not care about preferred size. Use e.g GridBagLayout with proper constraints or you can BoxLayout (with horizontal flow) placing the table first and an empty panel second as place holder.

java scrollpane with flowlayout

For some reason, I cannot this working. It should be simple really.
I've having a JFrame with a BorderLayout, which contains a JPanel (SOUTH) and a (CENTER) JPanel (itemPanel).
itemPanel should be wrapped in a scrollpane. Its width = x, and all of its children shares its length, so it basically works like a table with only 1 column.
For some reason, I cannot get the scrollpane to show the scrollbars (and scroll). In the JFrame:
setPreferredSize(dimension);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add("South",controlPanel);
JScrollPane scroll = new JScrollPane(itemPanel);
scroll.setBorder(null);
getContentPane().add("Center",scroll);
super.pack();
setVisible(true);
Initilizing and adding some dummy-panels to the itemPanel:
itemPanel = new ItemPanel(); // A JPanel with a flowlayout
itemPanel.setPreferredSize(new Dimension(dimension.width,0));
for(int i = 0; i < 20; i++){
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(0,50));
p.setBackground(i%2 == 0 ? Color.GREEN : Color.YELLOW);
itemPanel.add(p);
}
if omitting itemPanel.setPreferredSize(new Dimension(dimension.width,0)); the scrollpane shows the horizontal scrollbars, but since the flowlayout does not have a width to follow, it just shows the components in one row.
A FlowLayout does NOT recalculate the preferred size of a panel. The scrollbars only appear when the preferred size of the component is greater than the size of the scroll pane.
WrapLayout may be what you are looking for.

Categories

Resources