Класс javax.swing.Popup Эксперименты - PullRequest
0 голосов
/ 05 июня 2019

Я обнаружил класс javax.swing.Popup. Я написал код, чтобы проверить его поведение. Код показан ниже. Когда я запускаю код, после отображения JFrame я нажимаю кнопку ПОКАЗАТЬ, и отображается Popup. После этого я нажимаю кнопку HIDE, и Popup исчезает. Но потом, если я снова нажму кнопку ПОКАЗАТЬ, ничего не произойдет Popup появляется только после первого нажатия кнопки ПОКАЗАТЬ. Кроме того, если я сначала нажму кнопку СКРЫТЬ, прежде чем нажать кнопку ПОКАЗАТЬ, затем при нажатии кнопки ПОКАЗАТЬ Popup не отображается.

Я что-то упустил?
Я что-то не так делаю?

Признаюсь, я не исследовал это поведение. Я не искал в Интернете и не смотрел код для класса Popup или PopupFactory, просто из-за лени и в надежде, что кто-то сможет мне это объяснить.

Вот мой MCVE.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class PopupTest implements ActionListener, Runnable {
    private static final String HIDE = "HIDE";
    private static final String SHOW = "SHOW";
    private Popup popup;

    public void actionPerformed(ActionEvent actionEvent) {
        String actionCommand = actionEvent.getActionCommand();
        switch (actionCommand) {
            case HIDE:
                popup.hide();
                break;
            case SHOW:
                popup.show();
                break;
        }
    }

    public void run() {
        showGui();
    }

    private void showGui() {
        JFrame frame = new JFrame("Popup");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JLabel centerLabel = new JLabel("CENTER LABEL", SwingConstants.CENTER);
        frame.add(centerLabel, BorderLayout.CENTER);
        JPanel buttonsPanel = new JPanel();
        JButton showButton = new JButton(SHOW);
        showButton.addActionListener(this);
        buttonsPanel.add(showButton);
        JButton hideButton = new JButton(HIDE);
        hideButton.addActionListener(this);
        buttonsPanel.add(hideButton);
        frame.add(buttonsPanel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        JLabel popupLabel = new JLabel("Popup_Label");
        PopupFactory factory = PopupFactory.getSharedInstance();
        Point pt = centerLabel.getLocationOnScreen();
        int x = pt.x + 10;
        int y = pt.y - 10;
        popup = factory.getPopup(centerLabel, popupLabel, x, y);
    }

    public static void main(String[] args) {
        PopupTest instance = new PopupTest();
        EventQueue.invokeLater(instance);
    }
}

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Из документов для hide ():

"Скрывает и удаляет всплывающее окно. После удаления всплывающего окна вам больше не нужно вызывать методы для него. Удаленное всплывающее окно может быть восстановлено ипозже используется на основе PopupFactory. "

Таким образом, вот быстрая и грязная измененная версия, которая работает.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class PopupTest implements ActionListener, Runnable {

  private static final String HIDE = "HIDE";
  private static final String SHOW = "SHOW";
  private Popup popup;
  private JLabel centerLabel;
  private JLabel popupLabel = new JLabel("Popup_Label");
  private PopupFactory factory = PopupFactory.getSharedInstance();

  public void actionPerformed(ActionEvent actionEvent) {
    String actionCommand = actionEvent.getActionCommand();
    switch (actionCommand) {
      case HIDE:
        if (popup == null) {
          return;
        }
        popup.hide();
        popup = null; // necessary to avoid using the disposed popup
        break;

      case SHOW:
        if (popup != null) { // it's already showing
          return;
        }
        Point pt = centerLabel.getLocationOnScreen();
        int x = pt.x + 10;
        int y = pt.y - 10;
        popup = factory.getPopup(centerLabel, popupLabel, x, y);
        popup.show();
        break;
    }
  }

  public void run() {
    showGui();
  }

  private void showGui() {
    JFrame frame = new JFrame("Popup");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    centerLabel = new JLabel("CENTER LABEL", SwingConstants.CENTER);
    frame.add(centerLabel, BorderLayout.CENTER);
    JPanel buttonsPanel = new JPanel();
    JButton showButton = new JButton(SHOW);
    showButton.addActionListener(this);
    buttonsPanel.add(showButton);
    JButton hideButton = new JButton(HIDE);
    hideButton.addActionListener(this);
    buttonsPanel.add(hideButton);
    frame.add(buttonsPanel, BorderLayout.PAGE_END);
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);
  }

  public static void main(String[] args) {
    PopupTest instance = new PopupTest();
    EventQueue.invokeLater(instance);
  }
}
1 голос
/ 05 июня 2019

https://docs.oracle.com/javase/7/docs/api/javax/swing/Popup.html#hide()

Документация, которую вы выбрали, чтобы не читать, совершенно ясно, что hide() избавляется от Popup, и любые дальнейшие вызовы метода для этого Popup приведут к неопределенному поведению.

Вы должны каждый раз создавать новый экземпляр Popup.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...