问题
I have an S (very S) SCCE which illustrates the problem: there is a JTable and a JTree both contained in a JPanel with a BorderLayout. Most of the grid lines in the JTable show, but not the one at the left, and not the one at the top. Have tried experimenting with borders, with placing the JTable on its own dedicated JPanel, etc.
I have gleaned from the experts that it is a bad idea to call any of the setXXXSize methods, so have not resorted to setPreferredSize, for example. In the SSCCE you can swap the tree and table positions round by uncommenting the "EAST" line)
How do I make these obscured/missing gridlines reappear?
(NB the idea is eventually for the table to grow/shrink dynamically with the JTree, so that there are always the same number of rows in the table and the tree... hence the desire to contain both components on the same JPanel).
SSCCE:
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class TableGridProb {
public static void main( String[] args ) throws InterruptedException, InvocationTargetException{
EventQueue.invokeAndWait( new Runnable(){
@Override
public void run() {
JFrame frame = new JFrame( "Table Grid Prob" );
frame.setSize( 800, 300 );
frame.setVisible( true );
JSplitPane split_pane = new JSplitPane();
JScrollPane split_jsp = new JScrollPane( split_pane );
JPanel left_panel = new JPanel();
left_panel.setLayout( new BorderLayout() );
JTree jt = new JTree();
jt.setRowHeight( 20 );
left_panel.add( jt, BorderLayout.WEST );
// left_panel.add( jt, BorderLayout.EAST );
JTable jtable = new JTable( 4, 1 );
// jtable.setBorder( new LineBorder( Color.green, 3 ));
jtable.setRowHeight( 20 );
left_panel.add( jtable, BorderLayout.CENTER );
split_pane.setLeftComponent( left_panel );
frame.getContentPane().add( split_jsp );
split_pane.setDividerLocation( 0.5d );
}
});
}
}
later
In answer to the suggestion that all I have to do is wrap this JTable in a JScrollPane... this doesn't appear to solve the problem, at least with the standard Java L&F. I have also tried various permutations of sitting the JTable on a JScrollPane on a JPanel, sitting the JTable on its own JPanel and giving the latter a LineBorder, etc. The problem appears to be a bit trickier. My chief suspects are Insets and the layout managers... but 1) neither of the getInsets methods of the JTable is called in the course of this code however 2) maybe a BorderLayout is not ideal. I did try GridLayout and BoxLayout but, as I recall, neither of these solved the problem...
later
even simpler SSCCE which illustrates the prob (cannot see left-hand vertical gridline)
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class TableGridProb2 {
public static void main( String[] args ) throws InterruptedException, InvocationTargetException{
EventQueue.invokeLater( new Runnable(){
@Override
public void run() {
JFrame frame = new JFrame( "Table Grid Prob2" );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane sp = new JScrollPane( new JTable( 20, 5 ));
frame.getContentPane().add( sp );
frame.pack();
frame.setVisible( true );
}
});
}
}
* later (6 Sep) *
screenshots for the two SSCCEs:
hope you can see the problem: missing vertical left-hand gridline (and top gridline it appears) in both cases...
回答1:
A few notes for reference:
I've incorporated @Reimeus' suggestion, but I'm not really sure what you want.
I'm sure the border is merely illustrative, but note that the API authors, "recommend that you put the component in a
JPanel
and set the border on theJPanel
." In particular, the green border obscures part of the first table row.Note that the gridlines belong to the UI delegate, as shown here; if this is critical, plan to test on each target L&F.
Unless you have a specific reason to wait on the initial thread, use
invokeLater()
.If the
JTable
dominates your initial appearance, overriding theScrollable
interface methodgetPreferredScrollableViewportSize()
is a reasonable compromise of the general guidelines here.Use
pack()
to leverage a component's preferred size.Make
setVisible()
last.
Addendum: Based on your update, TableGridProb2
, I added a colored border to an enclosing panel to see better. Indeed, com.apple.laf.AquaTableUI
leaves a one-pixel left margin, presumably for the selection rectangle. You might try this with your chosen L&F.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.plaf.ColorUIResource;
public class TableGridProb2 {
public static void main(String[] args) {
UIManager.put("Table.gridColor", new ColorUIResource(Color.gray));
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Table Grid Prob2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane sp = new JScrollPane(new JTable(20, 5));
JPanel p = new JPanel(new GridLayout());
p.setBorder(new LineBorder(Color.green, 4));
p.add(sp);
frame.getContentPane().add(p);
frame.pack();
frame.setVisible(true);
}
});
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.plaf.ColorUIResource;
public class TableGridProb {
public static void main(String[] args) {
UIManager.put("Table.gridColor", new ColorUIResource(Color.gray));
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Table Grid Prob");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel leftPanel = new JPanel(new BorderLayout());
JTree jt = new JTree();
jt.expandRow(1);
leftPanel.add(jt, BorderLayout.WEST);
JTable table = new JTable(20, 1) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(300, 200);
}
};
table.setBorder(new LineBorder(Color.green, 4));
table.setTableHeader(null);
leftPanel.add(new JScrollPane(table), BorderLayout.CENTER);
JSplitPane splitPane = new JSplitPane();
splitPane.setLeftComponent(leftPanel);
frame.add(splitPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
回答2:
Place the above JTable
in a JScrollPane
so that gridlines are drawn by that container. It appears that you dont want the table headers so you could do
jTable.setTableHeader(null);
leftPanel.add(new JScrollPane(jTable));
来源:https://stackoverflow.com/questions/18598971/jtable-grid-lines-disappear-unexpectedly