JTable网格线意外消失

时间:2013-09-03 18:19:43

标签: java swing layout jtable gridlines

我有一个S(非常S)SCCE来说明问题:JTa和JTree都包含在带有BorderLayout的JPanel中。 JTable中的大多数网格线显示,但不是左边的网格线,而不是顶部的网格线。尝试过使用边框,将JTable放在自己的专用JPanel等上。

我从专家那里得知,调用任何setXXXSize方法是个坏主意,所以没有使用setPreferredSize,例如。在SSCCE中,您可以通过取消注释“EAST”行来交换树和表位置。

如何重新出现这些模糊/缺失的网格线?

(NB最终的想法是使用JTree动态增长/缩小表,以便表和树中总有相同数量的行...因此希望在同一个表中包含两个组件的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 );

      }
        });
    }
}

回答我所要做的就是将这个JTable包装在JScrollPane中的建议......这似乎不能解决问题,至少使用标准的Java L& F。我还尝试了将JTable放在JPanel上的JScrollPane上的各种排列,将JTable放在自己的JPanel上,然后给后者一个LineBorder,等等。问题似乎有点棘手。我的主要嫌疑人是Insets和布局经理......但是 1)然而,在此代码的过程中,都没有调用JTable的getInsets方法 2)也许BorderLayout不理想。我确实尝试过GridLayout和BoxLayout,但我记得,这些都没有解决问题......

更简单的SSCCE,它说明了概率(看不到左手垂直网格线)

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 );
      }
    });
  }
}

*稍后(9月6日)*

两个SSCCE的截图:

Table Grid Prob

Table Grid Prob 2

希望您能看到问题:在两种情况下都缺少垂直左侧网格线(以及它出现的顶部网格线)......

2 个答案:

答案 0 :(得分:3)

一些注释供参考:

  • 我已经纳入@Reimeus的建议,但我不确定你想要什么。

  • 我确定边框只是说明性的,但请注意API authors,“建议您将组件放在JPanel中并在JPanel上设置边框}“。特别是,绿色边框遮挡了第一个表格行的一部分。

  • 请注意,网格线属于UI委托,如here所示;如果这很关键,计划对每个目标L& F进行测试。

  • 除非您有特定理由等待initial thread,否则请使用invokeLater()

  • 如果JTable支配您的初始状态,则覆盖Scrollable接口方法getPreferredScrollableViewportSize()是对一般准则here的合理妥协。

  • 使用pack()来利用组件的首选大小。

  • setVisible()持续。

附录:根据您的更新TableGridProb2,我在封闭的面板上添加了彩色边框,以便更好地查看。实际上,com.apple.laf.AquaTableUI留下了一个像素左边距,大概是选择矩形。您可以尝试使用您选择的L& F.

image

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);
            }
        });
    }
}

image

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);
            }
        });
    }
}

答案 1 :(得分:2)

将上述JTable放在JScrollPane中,以便该容器绘制网格线。看来你不想要表头,所以你可以做到

jTable.setTableHeader(null);
leftPanel.add(new JScrollPane(jTable));