【问题标题】:Some Lines of Code Dont Run某些代码行不运行
【发布时间】:2013-11-28 21:44:12
【问题描述】:

我正在制作一个聊天客户端,但我遇到了一些代码无法运行的问题。

public static void login(String userName, String password) throws XMPPException {

    ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222,"Work");
    connection = new XMPPConnection(config);

    try{
        connection.connect();
        connection.login(userName, password);
        System.out.println("Login Successful");
        //gui.removeAll();

        URL temp = start.class.getResource("slate.png");

        gui.window.remove(gui.password);
        gui.window.remove(gui.username);
        gui.window.remove(gui.login);
        gui.window.remove(gui.failed);
        gui.window.setContentPane(new JLabel(new ImageIcon(temp)));
        gui.window.setBackground(new Color(27,27,27));

        System.out.println("Reached 1");
        //displayBuddyList();
        gui.list2.setVisible(true);
        System.out.println("Reached 2");
        gui.list2.setText("text test");
        System.out.println("Reached 3");

    }
    catch(Exception e){
        gui.failed.setVisible(true);
    }


}

"gui.list2.setVisible(true)" 和 "gui.list2.setText("TestText")" 行接缝不起作用。但我得到了所有 System.out.println 消息。

“list2”是一个JTextArea,它已经添加了我一直使用的JFrame: 这是我的 gui 类中的代码:

window.add(list2);
list2.setBounds(0,0,window.getWidth(),window.getHeight());
list2.setVisible(false);

所有代码供进一步调查:http://pastebin.com/PcSPzgBN

【问题讨论】:

  • 这一切都发生在美国东部时间吗?如果是这样,是否有其他东西干扰了 EDT?
  • 把 gui.list2.setVisible(true); setText 调用之后。
  • @Quirliom 没用。
  • 和@John3136 什么是 EDT?
  • EDT 是事件调度线程。如果你把它卡住,Java 就没有机会为你画东西了。

标签: java swing visible


【解决方案1】:

您的源代码足够长,很难准确指出您引用的问题出在哪里。我认为可能正是这一行:

gui.window.setContentPane(new JLabel(new ImageIcon(temp))); // <- this line
gui.window.setBackground(new Color(27,27,27));

...
gui.list2.setText("text test");
...
gui.list2.setVisible(true);

设置内容窗格后,list2 可能不再在框架中。它可能在之前的内容窗格中 (gui.firstscreen?)。

不过,还有一些更普遍的问题。

我看到一个看起来像这样的模式:

SomeJComponent aComp1 = new SomeJComponent();

somewhere.add(aComp1);
aComp1.setBounds(/* ... */);
aComp1.setVisible(false);

SomeJComponent aComp2 = new SomeJComponent();

somewhere.add(aComp2);
aComp2.setBounds(/* ... */);
aComp2.setVisible(false);

基本上看起来您这样做是为了有时动态地切换框架上的可见组件。您的组件都是重叠的,您可以选择哪些是可见的以重新配置框架。我强烈建议不要这样做。

交换容器视图的“正确”方法是使用单独的面板并设置内容窗格(或者甚至更好地使用专门用于此目的的 JComponents,例如 JTabbedPane)。以下是一个简短的工作示例:

import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.BorderLayout;

public class PanelSwap {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new PanelSwap().frame.setVisible(true);
            }
        });
    }

    JFrame frame;
    JPanel panel1;
    JPanel panel2;

    PanelSwap() {

        frame = new JFrame();
        frame.setLocationRelativeTo(null);

        panel1 = new JPanel(new BorderLayout());

        JButton toPanel2 = new JButton("Goto Panel 2");
        toPanel2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setContentPane(panel2);
                frame.validate();
            }
        });

        panel1.add(toPanel2, BorderLayout.CENTER);

        panel2 = new JPanel(new BorderLayout());

        JButton toPanel1 = new JButton("Goto Panel 1");
        toPanel1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setContentPane(panel1);
                frame.validate();
            }
        });

        panel2.add(toPanel1, BorderLayout.CENTER);

        frame.setContentPane(panel1);
        frame.pack();
    }
}

如果您希望共享某些 GUI 元素,您可以改为将内容窗格设置为具有共享元素的面板,并向该面板添加/删除元素。使用 BorderLayout 之类的东西以获得最佳效果。

另一点是您需要在事件调度线程上与 GUI 进行交互。有关教程,请参阅 Concurrency in Swing。特别是“初始线程”“事件调度线程”

这就是invokeLater 的用途。可以更新 GUI 内部事件(actionPerformed 之类的方法),因为它们是在 EDT 上执行的。您应该在其他任何地方使用invokeLater。该规则有一些例外,但在大多数情况下,您需要在 EDT 上进行 Swing 工作。

最后一个更重要的是,您应该真正遵循Java code conventions 的名称,特别是类以大写字母开头。你的startgui 类应该是StartGUI。这更加令人困惑,因为您的 gui 类有一个名为 start 的方法。

【讨论】:

  • 谢谢!!我不敢相信在该块中添加gui.window.add(gui.list2) 已解决,我将尽快专注于重写我的代码。如果我遇到问题或什么,我可以给你发消息吗?
  • 因为我认为你有足够的代表来使用聊天,你可以尝试在那里向我打招呼。使用@ 键入用户名(如@DarkLlama)也会从聊天中发送提及通知。如果我不在 SO 你可以问这个问题。有时房间里还有其他人,或者我上车时可能会看到。
【解决方案2】:

在将组件设置为可见后,尝试重新绘制和(重新)验证 gui 容器(窗口)或 JTextArea 组件。

【讨论】:

  • like window.repaint() 我在 JFrame 和 JTextArea 上尝试了该方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 2012-04-15
  • 2012-05-03
  • 2014-11-13
相关资源
最近更新 更多