2016-08-23 46 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/) –