I have Googled for hours on this issue but nothing seems to work.
I have a JTable with a JPanel inside a frame. The table has data from a database but there is a considerable amount of data to store (hence require the JScrollPane)
Here is my code:
public GeneralDisplay()
{
Insets insets = getInsets();
panel = new JPanel();
scrollVert = new JScrollPane(panel);
scrollVert.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollHor = new JScrollPane(panel);
scrollHor.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
newSoftwareBtn = new JButton("New");
removeSofwtareBtn = new JButton("Remove");
editSofwtareBtn = new JButton("Edit");
ResultSet results;
try
{
results = statement.executeQuery("SELECT * FROM Software");
cSoftware = new JTable(buildTableModel(results));
}
catch(SQLException sqlEx)
{
JOptionPane.showMessageDialog(null, "Error: SQL error!");
//System.exit(1);
}
///////////////////////////////////////////////////
//Adding to form
///////////////////////////////////////////////////
getContentPane().add(panel);
cSoftware.setBackground(null);
cSoftware.getTableHeader().setBackground(null);
//pack();
panel.add(scrollVert);
panel.add(scrollHor);
panel.add(cSoftware.getTableHeader());
panel.add(cSoftware);
panel.add(newSoftwareBtn);
panel.add(removeSofwtareBtn);
panel.add(editSofwtareBtn);
panel.add(scrollVert);
panel.add(scrollHor);
panel.revalidate();
panel.repaint();
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//Position on form
//////////////////////////////////////////////////////
Dimension size = newSoftwareBtn.getPreferredSize();
newSoftwareBtn.setBounds(5 + insets.left, 480 + insets.top, size.width, size.height);
size = removeSofwtareBtn.getPreferredSize();
removeSofwtareBtn.setBounds(55 + insets.left, 480 + insets.top, size.width, size.height);
size = editSofwtareBtn.getPreferredSize();
editSofwtareBtn.setBounds(105 + insets.left, 480 + insets.top, size.width, size.height);
In the image, the JScrollPane is visible in the area marked with a red square. I have more data in the table which is not visible, which is why I thought to add the JScrollPane to the table, but I also have buttons on my panel below the table which is why I wanted to add it to the panel.
My code might not be great as I have followed several tutorials on how to overcome the problem and kind of mashed them together.
Any help appreciated!
EDIT:
I have noticed that I added my scrolls to the panel twice. I have now removed that but still did not resolve the issue if that's what you thought it was
The other image is what happened when I added a GridLayout to the panel
Firstly, you don't need to create two JScrollPanes in order to have both a vertical and a horizontal scrollbar.
As far as the ScrollPane being seperated from the rest of your components, you need to add your JTable to the ScrollPane and then add that to the JPanel. Something like this:
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.add(cSoftware);
panel.add(scrollPane);
//add buttons etc
In your original code, you added both your (empty) ScrollPanels as well as your table to the JPanel.
I think you confuse a JScrollPane for a JScrollBar:
A JScrollPane is a wrapper to which you add large content, and which will show JScrollBar (either vertical or horizontal, or both) when this content exceeds the size of the container.
A JScrollBar is the actual horizontal or vertical scroll bar that you click and scroll.
In general you should work with a JScrollPane and let it take care of the scroll bars for you.
Based on the above, the answer to your question is:
Add the JTable to the JScrollPane (new JScrollPane(table);). You need only one JScrollPane in your situation.
Add the JScrollPane to the JPanel (To which you can also add your buttons)
Add the JPanel to the JFrame
Additionally:
You should use layout managers (By default, a JPanel has a FlowLayout, which might not be very convenient).
You don't need to add your table and your table's header separately.
You don't need to use repaint() or revalidate()
Related
I'm currently trying to figure out how to get different layouts for different parts of a JFrame.
-> I currently have my JFrame content pane set with a BorderLayout
-> I'd like to have the BorderLayout.CENTER as flexible as possible, while keeping some structure around it. So I would like to change only the layout of the CENTER part. Is that possible?
if so, how?
Ive tried to do something like that :
public ViewLvl(int number, JFrame window){
super();
this.level = new levels.Level(number);
this.setSize(TAILLE_FENETRE,TAILLE_FENETRE);
this.setPreferredSize(new Dimension(TAILLE_FENETRE,TAILLE_FENETRE));
this.setMaximumSize(new Dimension(TAILLE_FENETRE,TAILLE_FENETRE));
Container mainPane = window.getContentPane();
mainPane.setLayout(new BorderLayout());
JPanel game = new JPanel();
game.setLayout(null);
JButton b1 = new JButton("one");
game.add(b1);
Insets insets = game.getInsets();
Dimension size = b1.getPreferredSize();
b1.setBounds(25 + insets.left, 5 + insets.top,
size.width, size.height);
mainPane.add(game, BorderLayout.CENTER);
}
But the result is no visual output at all, while I was expecting one randomly placed button in the center part of the window
I want to add the possibility for my users to add a comment on a form. To display them, I created JPanel inside a simple JScrollPane. I set the layout of this JPanel to BoxLayout because I wish to add them all in only one column and it seemed to be the easiest way by calling BoxLayout.Y_AXIS in the constructor. I also tried GridLayout and GridBagLayout but it was not what I was looking for.
My problem is that when a JPanel has the BoxLayout layout, it's width automatically is the same as it's container, but my container is a JScrollPane and the caret hides the right side of my comment!
You can see the JTextField and a JButton on the bottom left, here's the code on the click event :
private void btnAjoutCommentaireActionPerformed(java.awt.event.ActionEvent evt) {
//I take the text from the JTextField and format it to html
String formattedComment = "<html><br><div style='width:280px;'>" +
txtArCommentaire.getText().replaceAll("\n", "<br>") +
"</div><br></html>";
JLabel label = new JLabel(formattedComment);
//I add a blue border
label.setBorder(new TitledBorder(new EtchedBorder(Color.lightGray, Color.blue), ConfigUser.getCu().toString()));
//this below doesn't work
label.setSize(280, 200);
//I tried adding a JPanel in between but it didn't really worked out
//JPanel panel = new JPanel();
//panel.setLayout(new GridLayout(1, 1));
//panel.setSize(297, 200);
//panel.add(label);
///pnlCommentaire is the JPanel inside the JScrollPane
pnlCommentaire.setLayout(new BoxLayout(pnlCommentaire, BoxLayout.Y_AXIS));
pnlCommentaire.add(label);
pnlCommentaire.revalidate();
pnlCommentaire.repaint();
}
As you can see I tried to adust the size in html using style='width:280px'and on the JLabel using label.setSize(280, 200); but none of them worked.
Do you have any idea on how I could resize this Jlabel?
EDIT :
I added a margin-right property to the div so that I can at least fully see the text in the JLabel but the right border is still hidden.
String formattedComment = "<html><br><div style='width:280px;margin-right:50px;'>" +
txtArCommentaire.getText().replaceAll("\n", "<br>") +
"</div><br></html>";
This is my plugin to the application with Miglayout:
This is MigLayout initialistion code, layout occupies 100% space of main panel:
resPanel.setLayout(new BoxLayout(resPanel, BoxLayout.Y_AXIS));
mainPanel.setLayout(new MigLayout("", "[][grow][grow][]", "[][][][grow]"));
mainPanel.add(new JLabel("Class expression"), "wrap");
mainPanel.add(owlDescriptionEditor, "growx,span 3");
mainPanel.add(calcButton, "wrap");
mainPanel.add(new JLabel("Definitions found"), "span 2");
mainPanel.add(new JLabel("Target signature"), "span 2,wrap");
JScrollPane jsp = new JScrollPane(resPanel);
mainPanel.add(jsp, "growy, growx, span 2");
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
mainPanel.add(new JScrollPane(deltaList), "growx,growy,span 2");
The problem is not working horizontal scrollbar of the left list, which is JPanel with BoxLayout, even though I call setVerticalScrollBarPolicy for it. JPanel is populated dynamically with this loop:
static void updateList(JPanel panel, Collection<OWLClassExpression> list) {
panel.removeAll();
for (int i = 0; i < 3; i++) {
for (OWLClassExpression p : list) {
String name = ((OWLNamedObject) p).getIRI().getShortForm();
JEditorPane jep = new JEditorPane("text/html", name+"QWQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
jep.setPreferredSize(new Dimension(200,20));
jep.setEditable(false);
jep.setOpaque(false);
panel.add(jep);
}
}
panel.add( Box.createVerticalStrut(400) );
}
I had to add last line to get vertical scrollbar working. If I don't add it, then its also missing, even though it has side effect of extra empty space in the bottom. How can I make scrollbars work properly?
jep.setPreferredSize(new Dimension(200,20));
Don't hardcode preferred sizes.
Each component will dynamcially determine its own preferred size based on the properties of the component (text, font etc.).
The layout manager can then dynamically determine the size of the panel based on the preferred size of each component and scrollbars will appear when required.
Also after you are finished adding all the components to the panel you need to use:
panel.revalidate();
To invoke the layout manager so the new size of the panel can be calculated.
I have a JFrame with JScrollPane in it. I have JPanel inside a scrollPane. And add multiline labels in it.
Everything is ok with multiline labels. I enclose my text in <HTML>..</HTML> tags.
And labels display its wrapped text.
"..." means long multiline text.
The problem is that useless area is displayed in the bottom.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(300, 300));
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
label1.setText("<html>" + "..." + "</html>");
panel.add(label1);
label2.setText("<html>" + "..." + "</html>");
panel.add(label2);
JScrollPane scroll = new JScrollPane(panel);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
frame.setContentPane(scroll);
frame.pack();
frame.setVisible(true);
EDIT.
So I have to set preferred size for inner JPanel. After that scrollPane draws its content(shows scrollbars) as its content has this fixed "inner panel preffered size".
If I won't set preferred size for the panel, JLabels wouldn't wrap the text.
After being layed out by the layout manager inner panel's size grows and became larger than previously set preferred size. Panel grows itself, its ok, I see wrapped text of labels in it. But scrollpane behaves incorrectly. It paints scroll as inner panel is still of prefferred size size. So I need correct resizing behaviour for JScrollPane.
use JTextPane or JEditorPane instead of JPanel contains bunch of JLabels
JTextPane or JEditorPane supporting stylled text or Html <= 3.2 for Java6
theoretically you can use JList, instead of Jlabels, but in this case you have to call for setPreferredScrollableViewportSize(new Dimension) same as for JPanel in the JScrollPane
EDIT
then use Highlighter
use built-in reader/writer for JTextComponents
This code puts a JTable into a JFrame (sole component of the whole UI):
JFrame frame = new JFrame( "Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = appender.createTable();
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
I also have some code to set the preferred size of the columns.
Nothing fancy. When the UI opens, the table takes up the whole view and I have no scroll bars. The combined preferred widths of the columns need more horizontal space than the windows is wide. Despite of that, there is no horizontal scroll bar and the columns are too narrow.
What do I have to do that
The columns are still resizable by the user
The current width is respected? I.e. when I change the width of one column, the width of the other columns should not change.
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
You can also add the scrollpane containing the table to a JPanel and then add the panel to the frame. That way the panel will change in size, not the scrollpane.