2016-08-23 85 views
1

我想創建一個網絡撲克服務器客戶端程序,我目前正在編寫包含圖形部分的客戶端,但是當我嘗試在我的代碼中將一個組件添加到JPanel時,在run方法中滿足某些條件,add方法似乎不起作用,但是在相同條件下操作JPanel的其他方法也適用。Java圖形添加方法

public class PokerClient { 

BufferedReader in; 
PrintWriter out; 
JFrame frame = new JFrame("Poker"); 

JPanel playerHandPanel; 

String serverAddress = "localhost"; 
String playerName; 

Card playerHand1, playerHand2; 


public PokerClient() { 

    // Layout GUI 
    frame.setSize(1100, 700); 
    frame.setResizable(true); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    playerHandPanel = new JPanel(new GridLayout(1, 2)); 
    playerHandPanel.setPreferredSize(new Dimension(600, 300)); 
    playerHandPanel.add(new CardComponent(new Card(3, Suit.CLUB))); //it works here 
    playerHandPanel.setVisible(true); 

    frame.add(playerHandPanel, BorderLayout.NORTH); 
    frame.setVisible(true); 
} 

/** 
* Prompt for and return the desired screen name. 
*/ 
private String getName() { 

    return JOptionPane.showInputDialog(
     frame, 
     "Choose a screen name:", 
     "Screen name selection", 
     JOptionPane.PLAIN_MESSAGE); 
} 

private Card constructCard(String line){ 
    int seperator = line.indexOf('/'); 
    int cardNum = Integer.parseInt(line.substring(0, seperator)); 
    Card card; 
    if(line.substring(seperator+1).startsWith("S")){ 
     card = new Card(cardNum, Suit.SPADE); 
    } else if(line.substring(seperator+1).startsWith("C")){ 
     card = new Card(cardNum, Suit.CLUB); 
    } else if(line.substring(seperator+1).startsWith("D")){ 
     card = new Card(cardNum, Suit.DIAMOND); 
    } else{ 
     card = new Card(cardNum, Suit.HEART); 
    } 
    System.out.println(card.toString()); 
    return card; 
} 

/** 
* Connects to the server then enters the processing loop. 
*/ 
private void run() throws IOException { 

    Socket socket = new Socket(serverAddress, 9050); 
    in = new BufferedReader(new InputStreamReader(
     socket.getInputStream())); 
    out = new PrintWriter(socket.getOutputStream(), true); 

    // Process all messages from server, according to the protocol. 
    while (true) { 
     String line = in.readLine(); 
     System.out.println(line); 
     if (line.startsWith("SUBMITNAME")) { 
//    String name = getName(); 
//    playerName = name; 
//    out.println(name); 
     } else if (line.startsWith("p1")) { 
      playerHandPanel.add(new CardComponent(new Card(4, Suit.SPADE)));//this doesn't work i can't figure out why 
      playerHandPanel.setBackground(Color.WHITE);//this worked 
      playerHandPanel.add(new JLabel("is this added"));//this doesn't work either 
      playerHandPanel.repaint(); 
     } 
    } 
} 


public static void main(String[] args) throws Exception { 
    PokerClient client = new PokerClient(); 
    client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    client.frame.setVisible(true); 
    client.run(); 
} 
} 

回答

3

幾個問題跳出來:

  • 你不添加或刪除組件之後,呼籲playerHandPanel revalidate() - 可能是一個主要貢獻者您的問題。
  • 你約束playerHandPanel的尺寸人爲
  • 而不是把它變成一個JScrollPane
  • 您的代碼標榜通過使主要Swing組件狀態更改關閉Swing事件線程或EDT
  • 你」 Swing線程規則再使用約束佈局,new GridLayout(1, 2)

可能的解決方案:

  • 是的,添加或刪除組件後,請在playerHandPanel上調用revalidate()。這將告訴它的佈局經理做他們的事情。
  • 如果要使用GridLayout,請以更靈活的方式進行操作,例如new GridLayout(1, 0)new GridLayout(1, 0),具體取決於您是要指定列數還是行數(0表示可變數量的列或行)
  • 考慮使用JList或JTable,這兩個組件更容易添加內容。
  • 學習並遵循Swing線程規則,包括僅在Swing事件線程上進行Swing狀態更改(例如添加或刪除組件,更改背景色...)。
+0

謝謝你的工作,我在哪裏可以找到Swing線程規則?我在教自己如何編寫代碼,所以我所知道的每件事都是基於像這樣的網站上的點點滴滴。 – Mike

+0

@Mike:請查看[Lesson:Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) –