Java图形添加方法

Java图形添加方法,java,swing,graphics2d,Java,Swing,Graphics2d,我正在尝试创建一个网络扑克服务器客户端程序,我目前正在编写客户端,其中包括图形部分,但是当我尝试在代码中向JPanel添加组件时,当run方法中满足特定条件时,add方法似乎不起作用,然而,在相同条件下操纵JPanel的其他方法也可以工作 public class PokerClient { BufferedReader in; PrintWriter out; JFrame frame = new JFrame("Poker"); JPanel playerHandPanel; Stri

我正在尝试创建一个网络扑克服务器客户端程序,我目前正在编写客户端,其中包括图形部分,但是当我尝试在代码中向JPanel添加组件时,当run方法中满足特定条件时,add方法似乎不起作用,然而,在相同条件下操纵JPanel的其他方法也可以工作

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

出现了几个问题:

  • 添加或删除组件后,您没有在playerHandPanel上调用
    revalidate()
    ,这可能是导致问题的主要原因
  • 您正在人为地限制playerHandPanel的大小
  • 而不是把它放到JScrollPane中
  • 您的代码通过关闭Swing事件线程或EDT对主要Swing组件状态进行更改来炫耀Swing线程规则
  • 您正在使用约束布局,
    newgridlayout(1,2)
可能的解决办法:

  • 是,添加或删除组件后,请在playerHandPanel上调用
    revalidate()
    。这将告诉它的布局经理做他们的事情
  • 如果要使用GridLayout,请以更灵活的方式执行,例如,
    new GridLayout(1,0)
    new GridLayout(1,0)
    ,具体取决于您是否要指定列数或行数(
    0
    表示列数或行数可变)
  • 考虑使用JList或JTable,这两个组件更容易添加内容
  • 一定要学习并遵循Swing线程规则,包括仅在Swing事件线程上进行Swing状态更改(例如添加或删除组件、更改背景颜色…)

谢谢您的帮助,我在哪里可以找到Swing线程规则?我在自学如何编码,所以我所知道的一切都是基于像这样的网站上的点点滴滴。@Mike:请看一看