2011-10-07 182 views
2

我試圖將多個JLists放入JPanel和JScrollPane中的JPanel。問題是,當我將JScrollPane添加到公式中時,JList和外部邊界之間存在一個空格,我該如何擺脫這個邊界,以便水平填充?刪除JScrollPane中的邊框

這是一個小的示例代碼,用JLabel而不是JList來演示此問題。

/編輯:它似乎是Windows的東西,它在Mac OS上運行良好。

import java.awt.*; 
import javax.swing.*; 

public class Test extends JFrame 
{ 
    public static void main(String[] args) 
    { 
     Test test = new Test(); 
    } 

    public Test() 
    { 
     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new BorderLayout());   
     this.setDefaultCloseOperation(EXIT_ON_CLOSE);   
     this.setContentPane(contentPane);   
     this.setMinimumSize(new Dimension(400, 300)); 

     JScrollPane sp = new JScrollPane(createLeftPane()); 
     sp.setBorder(BorderFactory.createLineBorder(Color.yellow)); 
     this.add(sp, BorderLayout.WEST); 

     LookAndFeel.installBorder(sp, "BorderFactory.createEmptyBorder()");   

     StackTraceElement[] st = Thread.currentThread().getStackTrace(); 
     for(int i = 0; i < st.length; i++) { 
      System.out.println(st[i]); 
     } 

     this.pack(); 
     this.setLocationRelativeTo(null); 
     this.setVisible(true); 

    } 

    private JPanel createLeftPane() 
    { 
     JPanel panel = new JPanel(); 
     panel.setLayout(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 
     c.fill = GridBagConstraints.HORIZONTAL; 
     JLabel label = new JLabel("TEST LABEL"); 
     label.setBorder(BorderFactory.createLineBorder(Color.blue)); 
     panel.add(label, c); 
     panel.setBorder(BorderFactory.createLineBorder(Color.red)); 

     return panel; 
    }   
} 

下面是截圖(第一個是沒有滾動面板) JScrollPane Problems

堆棧跟蹤:

java.lang.Thread.getStackTrace(Thread.java:1479) 
test.Test.<init>(Test.java:27) 
test.Test.main(Test.java:10) 

/編輯:一些試驗和錯誤之後,我發現,當我添加一個c.weightx = 0.5到它橫向填充的約束,但是當scrollPane變得比它的內容大時,它會變寬,這很奇怪。看下面的截圖:

enter image description here

+0

JScrollPane的邊界任何邊界+1發佈SSCCE。你可以添加一個截圖嗎? –

+0

@ Eng.Fouad截圖添加了 – Jesse

回答

1

你意味着這樣???

enter image description here

import java.awt.*; 
import java.io.File; 
import javax.swing.*; 
import javax.swing.filechooser.FileSystemView; 

public class FilesInTheJList { 

    private static final int COLUMNS = 5; 
    private Dimension size; 

    public FilesInTheJList() { 
     final JList list = new JList(new File("C:\\").listFiles()) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public Dimension getPreferredScrollableViewportSize() { 
       if (size != null) { 
        return new Dimension(size); 
       } 
       return super.getPreferredScrollableViewportSize(); 
      } 
     }; 
     list.setFixedCellHeight(50); 
     list.setFixedCellWidth(150); 
     size = list.getPreferredScrollableViewportSize(); 
     size.width *= COLUMNS; 
     list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 
     list.setCellRenderer(new MyCellRenderer()); 
     list.setVisibleRowCount(0); 
     list.setLayoutOrientation(JList.HORIZONTAL_WRAP); 

     JFrame f = new JFrame("Files In the JList"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new JScrollPane(list)); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       FilesInTheJList fITJL = new FilesInTheJList(); 
      } 
     }); 
    } 

    private static class MyCellRenderer extends JLabel implements ListCellRenderer { 

     private static final long serialVersionUID = 1L; 

     @Override 
     public Component getListCellRendererComponent(JList list, Object value, 
       int index, boolean isSelected, boolean cellHasFocus) { 
      if (value instanceof File) { 
       File file = (File) value; 
       setText(file.getName()); 
       setIcon(FileSystemView.getFileSystemView().getSystemIcon(file)); 
       if (isSelected) { 
        setBackground(list.getSelectionBackground()); 
        setForeground(list.getSelectionForeground()); 
       } else { 
        setBackground(list.getBackground()); 
        setForeground(list.getForeground()); 
       } 
       setPreferredSize(new Dimension(250, 25)); 
       setEnabled(list.isEnabled()); 
       setFont(list.getFont()); 
       setOpaque(true); 
      } 
      return this; 
     } 
    } 
} 

。通過@trashgod here

+0

不,你的代碼中沒有scrollPane。 – Jesse

+0

和代碼行'f.add(new JScrollPane(list));'是不是正確的JScrollPane定義,是否有另一種方式我必須定義:-) – mKorbel

+0

對不起,我的搜索沒有找到它,我的壞:) – Jesse

3

問題

similair但更好的方法是不是滾動窗格的原因。因爲您將標籤添加到JPanel。默認情況下,面板使用每個組件周圍有5像素垂直/水平間隙的FlowLayot。

更改FlowLayout以使用0間隔或使用不同的佈局。也許BoxLayout。

+0

我已經將它更改爲GridBagLayout,所以不是這樣。 – Jesse

+0

+1也許你是對的,但我仍然... – mKorbel

+0

@Jesse是你想填充JList項目的JScrollPane在兩個directstions? – mKorbel

2

當我在我的Mac上運行它時,問題不會發生,因此顯然這是Windows的問題。

除了爲background,​​,fontopaqueBasicPanelUI預期的UI默認安裝了一個邊界,而com.apple.laf.AquaPanelUI(顯然)沒有。

LookAndFeel.installBorder(p,"Panel.border"); 

您可以嘗試將其設置爲null

+0

感謝您的回答,我試着將它設置爲null像這樣: LookAndFeel.installBorder(sp,null); 但它在java.util.Hashtable.get(Hashtable.java:334)(sp是我的JScrollPane)引發nullPointerException – Jesse

+0

編輯您的答案以包含您修訂的[sscce](http://sscce.org/)和堆棧跟蹤。需要一個空白邊框,例如'BorderFactory.createEmptyBorder()'。 – trashgod

+0

我修改了我的SSCCE幷包含了堆棧軌道。我不得不查看如何使用堆棧跟蹤,所以我希望我以正確的方式做到了。 'BorderFactory.createEmptyBorder()'不起作用,但我不確定我是否以正確的方式做到了這一點。 – Jesse

3

component.setBorder(null)除去對已設置的組件

+0

很好的答案!我很長一段時間尋找這個問題的解決方案,這個簡單的解決方案的工作原理!感謝它。 – PetrS

0

trashgod的解決方案與

LookAndFeel.installBorder(scrollpane,BorderFactory.createEmptyBorder().toString()); 
0

爲我工作。您還可以刪除使用

JScrollPane yourScrollPane = new JScrollPane(); 
yourScrollPane.setBorder(BorderFactory.createEmptyBorder());