2015-08-31 50 views
1

對不起,如果這是一個愚蠢的問題,我是Java Swing UI的新手。 我想開發一個能夠抓取我的Steam成就的程序,而且我有這個基本代碼,但現在我想爲它創建一個UI。Java Swing JScrollPane包含更多窗格不滾動?

以下代碼是UiHandler類,還有很多其他的,但它們與此問題無關。這個類基本上只給出兩個對話框,詢問用戶和應用程序ID,然後給出一個滾動框,其中包含所有成就和值。相反,列表會熄滅屏幕,沒有任何滾動選項。

問題是我的scrollPanel(mainPanel內部)似乎沒有滾動(它沒有滾動條在側面,滾動輪什麼都不做)。我期望scrollPanel的內容(這是面板,具有存儲在地圖中的所有成就的列表)將滾動。

這是使用滾動面板我的第一次,所以我真的不知道我在做什麼....

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.GridLayout; 
import java.awt.event.WindowEvent; 
import java.util.Iterator; 
import java.util.Map; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class UserInterface extends JFrame { 

public UserInterface() { 
    initUI(); 
} 

@SuppressWarnings("unchecked") 
private void initUI() { 

    UserInteractionHandler uiHandler = new UserInteractionHandler(); 

    setTitle("Steam Stats"); 
    setSize(500, 400); 
    setLocationRelativeTo(null); 
    setDefaultCloseOperation(DISPOSE_ON_CLOSE); 

    JPanel panel = new JPanel(new GridLayout(0, 1)); 

    JLabel header = new JLabel("Steam Stats", SwingConstants.CENTER); 
    header.setFont(new Font("trebuchet ms", Font.BOLD, 20)); 
    panel.add(header); 


    String userId = JOptionPane.showInputDialog("Steam ID 64"); 
    String appId = JOptionPane.showInputDialog("App Id of Game"); 

    Map<String, Integer> allAchievements = uiHandler.getAllAchievements(appId, userId); 

    @SuppressWarnings("rawtypes") 
    Iterator it = allAchievements.entrySet().iterator(); 
    while (it.hasNext()) { 
     Map.Entry<String, Integer> pair = (Map.Entry<String, Integer>) it.next(); 

     JLabel key = new JLabel(pair.getKey()); 
     JLabel value = new JLabel(pair.getValue().toString()); 
     panel.add(key); 
     panel.add(value); 

     it.remove(); 
    } 

    JScrollPane scrollPanel = new JScrollPane(panel); 

    JPanel mainPanel = new JPanel(new GridLayout(0, 1)); 
    mainPanel.add(scrollPanel); 

    getContentPane().add(mainPanel, BorderLayout.NORTH); 



} 

public static void runUi() { 

    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      UserInterface ui = new UserInterface(); 
      ui.setVisible(true); 
     } 
    }); 
} 
} 

下面是這將產生窗口截圖: http://puu.sh/jVsto/4a4bcbdf6e.png

感謝您的幫助。 墊

回答

3

你的問題是,你正在添加JScrollPane BorderLayout.NORTH,並設置GUI的大小。這會將GUI限制到一定的大小,但不會限制BorderLayout.NORTH組件的大小,因此它將盡可能大地顯示JScrollPane的視口的全部內容,而不管它是否在小GUI中。

可能的解決方案:

  • 如果您添加JScrollPane的到BorderLayout.CENTER位置,這將實際工作。
  • 如果可能,您將希望避免設置任何尺寸。
  • 你可以限制首選大小JScrollPane的視口的
  • 我最喜歡的解決辦法:用一個JScrollPane內的JList的顯示數據,並指定列表中的可見行通過setVisibleRowCount(...)計數。

例如:

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.GridLayout; 
import java.awt.event.WindowEvent; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class UserInterface extends JFrame { 

    public UserInterface() { 
     initUI(); 
    } 

    @SuppressWarnings("unchecked") 
    private void initUI() { 

     UserInteractionHandler uiHandler = new UserInteractionHandler(); 

     setTitle("Steam Stats"); 
     // !! setSize(500, 400); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 

     JPanel panel = new JPanel(new GridLayout(0, 1)); 

     JLabel header = new JLabel("Steam Stats", SwingConstants.CENTER); 
     header.setFont(new Font("trebuchet ms", Font.BOLD, 20)); 
     panel.add(header); 

     String userId = JOptionPane.showInputDialog("Steam ID 64"); 
     String appId = JOptionPane.showInputDialog("App Id of Game"); 

     Map<String, Integer> allAchievements = uiHandler.getAllAchievements(
       appId, userId); 

     DefaultListModel<MyPair> listModel = new DefaultListModel<>(); 
     JList<MyPair> pairList = new JList<>(listModel); 
     pairList.setCellRenderer(new MyPairRenderer()); 
     pairList.setVisibleRowCount(20); 

     @SuppressWarnings("rawtypes") 
     Iterator it = allAchievements.entrySet().iterator(); 
     while (it.hasNext()) { 
      Map.Entry<String, Integer> pair = (Map.Entry<String, Integer>) it 
        .next(); 

      MyPair myPair = new MyPair(pair.getKey(), pair.getValue()); 
      listModel.addElement(myPair); 

      it.remove(); 
     } 

     //!! JScrollPane scrollPanel = new JScrollPane(panel); 
     JScrollPane scrollPanel = new JScrollPane(pairList); 

     JPanel mainPanel = new JPanel(new BorderLayout()); 
     mainPanel.add(header, BorderLayout.PAGE_START); 
     mainPanel.add(scrollPanel); 

     getContentPane().add(mainPanel, BorderLayout.PAGE_START); 
     pack(); // !! 

    } 

    public static void runUi() { 

     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       UserInterface ui = new UserInterface(); 
       ui.setVisible(true); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     UserInterface.runUi(); 
    } 
} 

class MyPair { 
    private String name; 
    private int value; 
    public MyPair(String name, int value) { 
     this.name = name; 
     this.value = value; 
    } 

    public String getName() { 
     return name; 
    } 

    public int getValue() { 
     return value; 
    } 

} 

class MyPairRenderer implements ListCellRenderer<MyPair> { 
    private JPanel panel = new JPanel(new GridLayout(1, 2, 5, 5)); 
    private JLabel nameLabel = new JLabel(); 
    private JLabel valueLabel = new JLabel(); 

    public MyPairRenderer() { 
     panel.add(nameLabel); 
     panel.add(valueLabel); 
    } 

    @Override 
    public Component getListCellRendererComponent(JList<? extends MyPair> list, 
      MyPair value, int index, boolean isSelected, boolean cellHasFocus) { 
     if (value != null) { 
      nameLabel.setText(value.getName()); 
      valueLabel.setText("" + value.getValue()); 
     } 
     return panel; 
    } 

} 
+0

這出色的作品,謝謝! –