【问题标题】:JScrollPane breaking right to left orientationJScrollPane 打破从右到左的方向
【发布时间】:2013-08-28 22:57:13
【问题描述】:

我的应用程序分为两个主要组件:

  • JLabelJTableHeader 组成的标头
  • 一个JScrollPane 包含一个JTable

JTableHeader 在单独的面板中的原因是它不应该滚动。表中的列都设置了首选/最大宽度(中间的列除外),因此当调整框架大小时,只有列应该改变其宽度。

编辑:我相信我可以使用JScrollPane.setColumnHeaderView( JTable.getTableHeader() ); 让表头保持静态 - 据我所知,我得到的代码就是这样并且更改它不会影响手头的问题。

JScrollPane 打破了JTableHeader 的从右到左 (RTL) 方向,我遇到了问题。 JTableHeader 将在左侧对齐,而 JTable 将在右侧对齐。

这个问题类似于here 发布的内容,指向这个未解决的bug。我不完全确定这是我看到的问题,因为 JTableHeader 不应该在滚动窗格中。此外,建议的解决方案不起作用,因为我确实需要滚动条位于左侧,这在 RTL 方向中是预期的。

如何修复JTableHeader 的方向,同时仍保持自动调整列大小的能力?

编辑:向 tablePanel 添加了一个 JButton,因为它应该在那里。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;

public class SwingTest {

  public static void main( String[] args ) {
    final JFrame frame = new JFrame( "RTL Test" );

    //ComponentOrientation orientation = ComponentOrientation.LEFT_TO_RIGHT;
    ComponentOrientation orientation = ComponentOrientation.RIGHT_TO_LEFT;

    frame.setComponentOrientation( orientation );

    /* Build and populate table */
    String data[][] = {
      { "1", "foo", "bar", "5000" },
      { "2", "wtf", "RTL", "20000" },
      { "3", "hello", "world", "30000" },
      { "4", "why", "align", "25000" },
      { "5", "foo", "bar", "5000" },
      { "6", "wtf", "RTL", "20000" },
      { "7", "hello", "world", "30000" },
      { "8", "why", "align", "25000" },
      { "9", "hello", "world", "30000" },
      { "10", "hello", "world", "30000" },
      { "11", "hello", "world", "30000" }
    };
    String col[] = { "First", "Second", "Third", "Fourth" };
    DefaultTableModel model = new DefaultTableModel( data, col );
    /* Simply overrides isCellEditable to always * return false */
    JTable table = new NonEditableTable( model );
    /* By using AUTO_RESIZE_OFF, the header becomes correctly aligned but columns no longer auto-resize */
    //table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
    table.setAutoResizeMode( JTable.AUTO_RESIZE_ALL_COLUMNS );
    table.applyComponentOrientation( orientation );

    /* Set all but 3rd column to have a preferred/max size */
    TableColumn tableColumn = null;
    for ( int i = 0; i < table.getColumnCount(); i++ ) {
      if ( i != 2 ) {
        tableColumn = table.getColumnModel().getColumn( i );
        tableColumn.setMaxWidth( 100 );
        tableColumn.setPreferredWidth( 100 );
      }
    }

    /* Pretty */
    JTableHeader header = table.getTableHeader();
    header.setForeground( Color.RED );

    /* ScrollPane = JScrollPane + JTable */
    JPanel tablePanel = new JPanel( new BorderLayout() );
    tablePanel.add( BorderLayout.CENTER, table );
    tablePanel.add( BorderLayout.CENTER, new JButton( "Doh!" ) );
    JScrollPane scrollPane = new JScrollPane( tablePanel );
    scrollPane.setBorder( BorderFactory.createEmptyBorder() );
    /* NOTE: This is what breaks the header when using AUTO_RESIZE_ALL_COLUMNS, comment out to see */
    scrollPane.setComponentOrientation( orientation );

    /* Header */
    JPanel headerPanel = new JPanel( new BorderLayout() );
    headerPanel.add( BorderLayout.NORTH, new JLabel( "SWING TEST" ) );
    headerPanel.add( BorderLayout.CENTER, Box.createVerticalStrut( 5 ) );
    headerPanel.add( BorderLayout.SOUTH, table.getTableHeader() );
    headerPanel.applyComponentOrientation( orientation );

    /* Main = Header + ScrollPane */
    JPanel mainPanel = new JPanel( new BorderLayout() );
    mainPanel.add( BorderLayout.NORTH, headerPanel );
    mainPanel.add( BorderLayout.CENTER, scrollPane );

    /* Add to main frame */
    frame.add( mainPanel );
    frame.setUndecorated( true );
    frame.getRootPane().setWindowDecorationStyle( JRootPane.PLAIN_DIALOG );
    frame.setSize( 500, 200 );
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

    SwingUtilities.invokeLater( new Runnable() {

      @Override
      public void run() {
        frame.setVisible( true );
      }
    } );

  }

  @SuppressWarnings( "serial" )
  public static class NonEditableTable extends JTable {

    public NonEditableTable( DefaultTableModel model ) {
      super( model );
    }

    @Override
    public boolean isCellEditable( int row, int column ) {
      return false;
    }

  }
}

【问题讨论】:

  • 我建议发帖your question to Coderanch,这里是@Darryl Burke 的大部分LTR 和Swing 解决方法的作者,然后请通知两个论坛上的交叉发帖
  • 实际上,我不明白你想要实现什么:当表格本身不滚动时,标题不滚动听起来很奇怪.. 从技术上讲,问题与 scrollPane 无关(不能是相关的,因为标题没有添加到 scrollPane 的任何地方;),即使它的 CO 是正确的,只是对齐方式很奇怪。删除它与表的关联可以解决这个问题,并没有深入了解为什么会发生这种情况。在你的情况下,我会重新开始:描述你的要求,让我们看看如何在不做任何不寻常的事情的情况下实现它们
  • 冻结一行(在本例中为标题)实际上很常见,这样当表格滚动时,您无需向上滚动即可轻松查看标题。无论问题的根源如何,我的要求都没有改变。表格标题应根据方向右对齐,并且列应自动调整大小。
  • It's actually quite common to freeze a row (in this case the header) so that as the table scrolls, you can easily see the header without having to scroll back up - 这是 JScrollPane 的默认行为。当您垂直滚动时,标题会显示在顶部。如果您水平滚动,标题会水平滚动以匹配正在滚动的列。
  • 即使您移除 RIGHT_TO_LEFT 翻转,该程序的行为也非常奇怪。

标签: java swing jtable right-to-left jtableheader


【解决方案1】:

做这样的事情怎么样?并且您可以更好地控制方向。

JPanel headerPanel = new JPanel( new BorderLayout() );

JPanel headerPan = new JPanel();
JLabel xxx = new JLabel( "SWING TEST" );
xxx.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

headerPan.add(xxx);

希望对您有所帮助。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 2014-10-03
  • 1970-01-01
  • 2017-04-28
相关资源
最近更新 更多