2013-08-28 79 views
2

我的應用程序被分成成兩個主要組件:JScrollPane的右斷裂向左取向

  • 報頭由以下組成的JLabelJTableHeader
  • 一個JScrollPane含有JTable

原因JTableHeader是在一個單獨的面板中,因爲它不應該滾動。表中的列都設置了首選/最大寬度集(中間的列除外),所以當框架被調整大小時,只有列應該改變其寬度。

編輯:我相信我可以使用JScrollPane.setColumnHeaderView(JTable.getTableHeader());得到表頭保持靜態 - 我得到的代碼就是這樣,並改變它並不影響手頭的問題,據我所知。

我有一個JScrollPane打破JTableHeader從右到左(RTL)方向的問題。 JTableHeader將在左側對齊,而JTable將在右側對齊。

這個問題類似於發佈的here,它指向了這個未解決的bug。我不完全確定這是我看到的問題,因爲JTableHeader不應該在滾動窗格中。此外,建議的解決方案無法正常工作,因爲我確實需要將滾動條放在左側,因爲它將以RTL方向預期。

如何修復JTableHeader的方向,同時仍然保留自動調整列大小的功能?

編輯:添加一個JButton到tablePanel,因爲它假設在那裏。

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

    } 
} 
+1

我建議發佈[您的問題到Coderanch](http://www.coderanch.com/forums/f-2/GUI),這裏是@Darryl Burke作者的LTR&Swing的大部分解決方法,那麼請在兩個論壇 – mKorbel

+0

實際上通知有關crossposting,我不明白你想實現什麼:聽起來很奇怪,表頭本身不滾動時,表本身..技術上,這個問題是無關的scrollPane(可以沒有關係,因爲頭文件沒有添加到scrollPane的任何地方;),即使它的CO是正確的,只有對齊是奇怪的。刪除它與桌面的關聯修復,並沒有挖掘爲什麼發生。在你的鞋子裏,我會重新開始:描述你的需求,讓我們看看如何在不做任何不尋常的事情的情況下實現它們 – kleopatra

+0

實際上,凍結一行(在這種情況下是標題)是很常見的,這樣當表滾動時,看到標題而不必向上滾動。無論問題的根源如何,我的要求都沒有改變。表頭應該根據方向右對齊,並且列應自動調整大小。 – nevets1219

回答

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

希望有幫助。

+0

我可以從CodeRanch獲得答案,網址爲http://www.coderanch.com/t/618982/GUI/java/JScrollPane-header-lose-component-orientation – nevets1219