Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 工具提示文本呈现为不可链接的JButton_Java_Swing_Jbutton_Event Dispatch Thread - Fatal编程技术网

Java 工具提示文本呈现为不可链接的JButton

Java 工具提示文本呈现为不可链接的JButton,java,swing,jbutton,event-dispatch-thread,Java,Swing,Jbutton,Event Dispatch Thread,当我将工具提示文本添加到JDialog中的JButton组件时,按钮(实际上,两个执行类似操作的按钮)的行为就像它被禁用一样(setEnabled(false))。我感觉它与实际的工具提示文本没有直接关系,而是在EDT上循环执行某些操作。不管怎样,这就是课堂 package org.carroll.dialogs.editing; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraint

当我将工具提示文本添加到JDialog中的JButton组件时,按钮(实际上,两个执行类似操作的按钮)的行为就像它被禁用一样(setEnabled(false))。我感觉它与实际的工具提示文本没有直接关系,而是在EDT上循环执行某些操作。不管怎样,这就是课堂

package org.carroll.dialogs.editing;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;
import org.carroll.data.school.AllCourses;
import org.carroll.data.settings.Settings;
import org.carroll.internal.InternalPanel;
import org.carroll.school.Course;
import org.carroll.utils.Logging;
import org.swing.Dialog;
import org.swing.Listeners;
import org.swing.dialogs.messages.ErrorMessage;

/**
 * Dialog for editing a course. Is custom to editing courses.
 *
 * @author Joel Gallant
 */
public class EditCourseDialog extends Dialog {

JButton save, done, cancel;
KeyListener doneListener = new Listeners.DoneListener() {
    @Override
    public void enterPressed() {
        if (!done.isFocusOwner()) {
            done.doClick();
        }
    }
};
static Course currentCourse;

/**
 * Creates dialog with default course selected.
 */
public EditCourseDialog() {
    super("Edit Course");
    currentCourse = AllCourses.getInstance().get(0);
}

/**
 * Creates dialog that selects a course by default.
 *
 * @param startingSelection default selection
 */
public EditCourseDialog(String startingSelection) {
    super("Edit Course");
    try {
        currentCourse = AllCourses.getInstance().get(startingSelection);
    } catch (NoSuchFieldException ex) {
        currentCourse = AllCourses.getInstance().get(0);
    }
}

public EditCourseDialog(Course startingCourse) {
    super("Edit Course");
    currentCourse = startingCourse;
}

void editCourse(String name, int credits, int units, int[] semester, int order) {
    Logging.log(name + " edited.");
    currentCourse.setName(name);
    currentCourse.setCredits(credits);
    currentCourse.setUnits(units);
    currentCourse.setSemester(semester);
    currentCourse.setOrder(order);
    if (!AllCourses.getInstance().getElements().contains(currentCourse)) {
        AllCourses.getInstance().add(currentCourse);
    }
    InternalPanel.COURSES.refresh();
}

@Override
protected void init() {
    GridBagLayout layout = new GridBagLayout();
    setLayout(layout);
    setPreferredSize(new Dimension(385, 280));

    Integer[] creditArray = {1, 3, 5};
    String[] semesterArray;
    try {
        semesterArray = new String[Integer.parseInt(Settings.getInstance().get("Semesters").getValue()) + 1];
        for (int x = 0; x < Integer.parseInt(Settings.getInstance().get("Semesters").getValue()); x++) {
            semesterArray[x] = String.valueOf(x + 1);
        }
        semesterArray[semesterArray.length - 1] = "Year";
    } catch (NoSuchFieldException ex) {
        semesterArray = new String[2];
        semesterArray[0] = "1";
        semesterArray[1] = "2";
    }

    final JComboBox<String> course = new JComboBox<>(AllCourses.getInstance().getNames());
    final JLabel nameLabel = new JLabel("Name"),
            creditsLabel = new JLabel("Credits"),
            unitsLabel = new JLabel("Units"),
            semesterLabel = new JLabel("Semester"),
            orderLabel = new JLabel("Order");
    final JTextField name = new JTextField(),
            units = new JTextField(),
            order = new JTextField();
    final JButton up = new JButton("↑"),
            down = new JButton("↓");
    final JComboBox<Integer> credits = new JComboBox<>(creditArray);
    final JComboBox<String> semester = new JComboBox<>(semesterArray);
    save = new JButton("Save");
    done = new JButton("Done");
    cancel = new JButton("Cancel");

    course.setSelectedItem(currentCourse.getName());

    String orderExpl = "<html>The order you are doing the courses in during the semester. "
            + "<br>It starts at 1, and goes on. (Do not make multiple courses with same order)</html>";
    orderLabel.setToolTipText(orderExpl);
    order.setToolTipText(orderExpl);
    up.setToolTipText(orderExpl);
    down.setToolTipText(orderExpl);

    name.setText(currentCourse.getName());
    name.setCaretPosition(0);
    units.setText(String.valueOf(currentCourse.getUnits()));
    credits.setSelectedItem(currentCourse.getCredits());
    semester.setSelectedItem(currentCourse.getSemesters().length > 1 ? "Year" : String.valueOf(currentCourse.getSemesters()[0]));
    order.setText(String.valueOf(currentCourse.getOrder()));

    up.setFont(up.getFont().deriveFont(Font.BOLD, (float) 14));
    down.setFont(up.getFont());
    course.addKeyListener(doneListener);
    name.addKeyListener(doneListener);
    units.addKeyListener(doneListener);
    credits.addKeyListener(doneListener);
    semester.addKeyListener(doneListener);
    order.addKeyListener(doneListener);
    done.addKeyListener(doneListener);
    cancel.addKeyListener(doneListener);

    save.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                int[] semesters;
                if (semester.getSelectedItem().equals("Year")) {
                    semesters = new int[Integer.parseInt(Settings.getInstance().get("Semesters").getValue())];
                    for (int x = 0; x < semesters.length; x++) {
                        semesters[x] = x + 1;
                    }
                } else {
                    semesters = new int[]{Integer.parseInt(semester.getSelectedItem().toString())};
                }
                editCourse(name.getText(), Integer.parseInt(credits.getSelectedItem().toString()),
                        Integer.parseInt(units.getText()), semesters,
                        Integer.parseInt(order.getText()));
            } catch (NumberFormatException ex) {
                new ErrorMessage(ex, "A number was entered wrong").createAndViewGUI();
            } catch (NoSuchFieldException ex) {
                new ErrorMessage(ex).createAndViewGUI();
            }
        }
    });
    done.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                int[] semesters;
                if (semester.getSelectedItem().equals("Year")) {
                    semesters = new int[Integer.parseInt(Settings.getInstance().get("Semesters").getValue())];
                    for (int x = 0; x < semesters.length; x++) {
                        semesters[x] = x + 1;
                    }
                } else {
                    semesters = new int[]{Integer.parseInt(semester.getSelectedItem().toString())};
                }
                editCourse(name.getText(), Integer.parseInt(credits.getSelectedItem().toString()),
                        Integer.parseInt(units.getText()), semesters,
                        Integer.parseInt(order.getText()));
                dispose();
            } catch (NumberFormatException ex) {
                new ErrorMessage(ex, "A number was entered wrong").createAndViewGUI();
            } catch (NoSuchFieldException ex) {
                new ErrorMessage(ex).createAndViewGUI();
            }
        }
    });
    cancel.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            dispose();
        }
    });
    up.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            AllCourses.getInstance().move(currentCourse.getName(), true);
            order.setText(String.valueOf(currentCourse.getOrder()));
            InternalPanel.COURSES.refresh();
        }
    });
    down.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            AllCourses.getInstance().move(currentCourse.getName(), false);
            order.setText(String.valueOf(currentCourse.getOrder()));
            InternalPanel.COURSES.refresh();
        }
    });

    course.addItemListener(new ItemListener() {
        @Override
        public void itemStateChanged(ItemEvent e) {
            try {
                currentCourse = AllCourses.getInstance().get(course.getSelectedItem().toString());
            } catch (NoSuchFieldException ex) {
                currentCourse = AllCourses.getInstance().get(course.getSelectedIndex());
            }
            name.setText(currentCourse.getName());
            units.setText(String.valueOf(currentCourse.getUnits()));
            credits.setSelectedItem(currentCourse.getCredits());
            semester.setSelectedItem(currentCourse.getSemesters().length > 1 ? "Year" : String.valueOf(currentCourse.getSemesters()[0]));
            order.setText(String.valueOf(currentCourse.getOrder()));
        }
    });

    GridBagConstraints constraints = new GridBagConstraints();

    constraints.fill = GridBagConstraints.BOTH;
    constraints.insets = new Insets(5, 8, 5, 8);
    constraints.weightx = 1;
    constraints.weighty = 1;
    constraints.gridwidth = 4;
    layout.addLayoutComponent(course, constraints);
    constraints.gridy = 1;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(nameLabel, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 3;
    layout.addLayoutComponent(name, constraints);
    constraints.gridy = 2;
    constraints.gridx = 0;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(creditsLabel, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 3;
    layout.addLayoutComponent(credits, constraints);
    constraints.gridx = 0;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(unitsLabel, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 3;
    layout.addLayoutComponent(units, constraints);
    constraints.gridy = 4;
    constraints.gridx = 0;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(semesterLabel, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 3;
    layout.addLayoutComponent(semester, constraints);
    constraints.gridy = 5;
    constraints.gridx = 0;
    layout.addLayoutComponent(orderLabel, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(up, constraints);
    constraints.gridx = 2;
    layout.addLayoutComponent(down, constraints);
    constraints.gridx = 3;
    layout.addLayoutComponent(order, constraints);
    constraints.gridy = 6;
    constraints.gridx = 0;
    layout.addLayoutComponent(save, constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 2;
    layout.addLayoutComponent(done, constraints);
    constraints.gridx = 3;
    constraints.gridwidth = 1;
    layout.addLayoutComponent(cancel, constraints);

    add(course);
    add(nameLabel);
    add(name);
    add(creditsLabel);
    add(credits);
    add(unitsLabel);
    add(units);
    add(semesterLabel);
    add(semester);
    add(orderLabel);
    add(up);
    add(down);
    add(order);
    add(save);
    add(done);
    add(cancel);
}

@Override
public void createAndViewGUI() {
    if (currentCourse != null) {
        super.createAndViewGUI();
    } else {
        new ErrorMessage(new NoSuchFieldException("No courses"), "No courses to edit").createAndViewGUI();
    }
}
这里需要注意的重要一点是init()是在EDT之外调用的,并且只有在调用setToolTiptText()方法时才会发生这种行为。在不同但结构相似的类中观察到相同的行为

这是导致EDT中出现问题的循环还是与工具提示文本的工作方式有关?(我从未使用过tooltiptext,而且对swing/java非常陌生)

如需更多信息,请询问


感谢

首先,切勿更新EDT以外的任何UI组件,这包括构造,您不知道组件何时会请求更新并导致重新绘制,或者何时实际连接到本机对等机

过去人们认为,只要将组件添加到其中的UI中,就可以在
EDT
之外初始化组件。这在当时是一种误解,Swing开发团队实际上表示这是一种糟糕的做法

您可能想阅读更多详细信息

其次,切勿在
EDT
中执行任何耗时的任务,它们将阻止
EDT
处理绘制和事件请求,使UI看起来没有响应


如果不知道循环运行了多长时间,就无法确定。我能提出的最好建议是注释掉
actionPerformed
方法的实际主体,然后再次测试它

首先,不要更新
EDT
之外的任何UI组件,这包括构造,您不知道组件何时会请求更新并导致重新绘制,也不知道它何时实际连接到本机对等机

过去人们认为,只要将组件添加到其中的UI中,就可以在
EDT
之外初始化组件。这在当时是一种误解,Swing开发团队实际上表示这是一种糟糕的做法

您可能想阅读更多详细信息

其次,切勿在
EDT
中执行任何耗时的任务,它们将阻止
EDT
处理绘制和事件请求,使UI看起来没有响应


如果不知道循环运行了多长时间,就无法确定。我能提出的最佳建议是注释掉执行的
操作方法的实际主体,然后再次测试它这里的问题是您的标签
orderLabel
在两个按钮上展开,
up
down
。我添加了一个绿色边框以突出显示:

按钮未被禁用,但鼠标单击被阻止,因为工具提示现在有一个覆盖的
MouseListener


解决方案是删除此标签的工具提示,或者缩小其大小,使其不会与按钮重叠。

这里的问题是,您的标签
orderLabel
在两个按钮上展开,
up
down
。我添加了一个绿色边框以突出显示:

按钮未被禁用,但鼠标单击被阻止,因为工具提示现在有一个覆盖的
MouseListener


解决方案是删除此标签的工具提示,或者缩小其大小,使其不会与按钮重叠。

谢谢您的建议。我最近刚刚了解了EDT,正如你所知道的,我还没有考虑到它。谢谢你的建议。我最近刚刚了解了EDT,正如你所知道的,我还没有考虑到它。
package org.swing;

import java.awt.Component;
import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import org.carroll.dialogs.MainFrame;

/**
 * Basic interface for all user dialogs. Extends {@link JFrame}.
 *
 * @author Joel Gallant
 */
public abstract class Dialog extends JDialog {

Component c = null;

/**
 * Creates a basic dialog that disposes on closing.
 *
 */
public Dialog() {
    super(MainFrame.getInstance());
}

/**
 * Creates a basic dialog that disposes on closing.
 *
 * @param location relative position of the window
 */
public Dialog(Component location) {
    this();
    this.c = location;
}

/**
 * Creates a basic dialog that disposes on closing.
 *
 * @param title title of the dialog
 */
public Dialog(String title) {
    super(MainFrame.getInstance(), title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}

/**
 * Creates a basic dialog that disposes on closing.
 *
 * @param title title of the dialog
 * @param location relative position of the window
 */
public Dialog(String title, Component location) {
    super(MainFrame.getInstance(), title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    this.c = location;
}

/**
 * Creates a basic dialog which follows the default close operation given in
 * the parameter.
 *
 * @param title title of the dialog
 * @param defaultCloseOperation default closing operation of the window
 */
public Dialog(String title, int defaultCloseOperation) {
    super(MainFrame.getInstance(), title);
    setDefaultCloseOperation(defaultCloseOperation);
}

/**
 * Creates a basic dialog which follows the default close operation given in
 * the parameter.
 *
 * @param title title of the dialog
 * @param defaultCloseOperation default closing operation of the window
 * @param location relative position of the window
 */
public Dialog(String title, int defaultCloseOperation, Component location) {
    this(title, defaultCloseOperation);
    this.c = location;
}

/**
 * Initializes everything needed to display the GUI.
 */
protected abstract void init();

@Override
public void dispose() {
    super.dispose();
    dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSED));
}

/**
 * Create all necessary components of the dialog and display it.
 */
public void createAndViewGUI() {
    init();

    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            pack();
            setLocationRelativeTo(c);
            setVisible(true);
        }
    });
}