Вопрос

Я создал приложение Swing с несколькими <сильными> JinternalFrames , который добавляется в jdesktoppane на событие щелчка мыши.Я хочу только один экземпляр одинаковой внутренней рамки , чтобы присутствовать на рабочем месте. Я не хочу, чтобы одинаковую раму появился дважды, когда пользовательОткрывает кадр.Если рамка уже открыта, то должно появиться сообщение об ошибке.!

Спасибо много :)

Это было полезно?

Решение

Не беспокойтесь с синглтоном анти-образцом.Вместо этого просто дайте свой класс Jinternalframe поле и создайте один экземпляр вашего JinternalFrame в конструкторе вашего класса или в объявлении переменной, и не создавать новую на щелчке мыши, а скорее отображать тот, который имеетуже был создан.Например, в насемештельном режиме, просто вызовите myInternalFrame.setVisible(true).Таким образом, если бы это было невидимо, теперь это видно, и если он уже виден, то он все еще виден и без изменений.Простой и простой.

Другие советы

Я создал приложение Swing с несколькими jinternalFrames ...

и

Я хочу только один экземпляр одной внутренней рамы ...

Так что примените bindleton dattern каждому из ваших детских классов Jinternalframe. Вы сможете использовать только один экземпляр класса, если класс соответствует шаблону синглтон.

Hovercraftfullofeeels, мужчина после моего собственного сердца, говорит не использовать синглтон, и я собираюсь не согласен. Singleton может быть очень мощным способом упорядочить вещи и избегать кода Bovertlate, сохраняя сильную систему и легко в обслуживании. Кроме того, его предположение, что вы просто отображаете уже открытый генеракодицетагCodCODCODCODCODE по двум способам: 1), сложно управлять на уровне кода и оставляет вашу систему хрупкой и сложно обновить в будущем и 2), когда концевые пользователи закрываются И вновь открывайте экран, они ожидают новый экземпляр , с обновленными данными и новыми компонентами. Не ожидается, что закрытие и возобновление будут одинаковыми случаями.

Другой ответчик говорит использовать Singleton, но не дает конкретного примера. Итак, я собираюсь дать вам код, который я разработал для моего приложения:

Это класс для JInternalFrame Singleton (ПРИМЕЧАНИЕ: причина, по которой она расширяет JInternalFrame, так что я могу легко использовать его в Builder GUI):

public abstract class VPanel extends JPanel {

    public static JDesktopPane desktopPane;

    public static void installDesktopPane(JDesktopPane desktopPane) {
        VPanel.desktopPane = desktopPane;
    }

    public VPanel(String name) {
        this.name = name;
        if(desktopPane == null)
            throw new IllegalStateException("VPanel is being used with a null desktop pane.");
    }
    static LinkedHashMap<Class, VPanel> self_panel_map;

    JInternalFrame self_jif;
    protected VPanel self_panel;
    boolean loading;
    boolean showing;

    public final String name;
    public abstract void init();

    public static VPanel showPanel(VPanel newInstance) {
        if(self_panel_map == null)
            self_panel_map = new LinkedHashMap<>();
        Class newInstanceClass = newInstance.getClass();
        if(self_panel_map.containsKey(newInstanceClass)) {
            VPanel oldInstance = self_panel_map.get(newInstanceClass);
            oldInstance.showing = oldInstance.self_jif.isVisible();
            if(!oldInstance.loading && !oldInstance.showing) {
                newInstance.loading = true;
                newInstance.self_panel = newInstance;
                newInstance.self_jif = new JInternalFrame(newInstance.name, true, true, true, true);
                newInstance.self_panel.init();
                self_panel_map.put(newInstanceClass, newInstance);
                return newInstance;
            } else if(oldInstance.showing) {
                try {
                    oldInstance.self_jif.setSelected(true);
                } catch (PropertyVetoException e) {
                    handleError(e);
                }
            }
            return oldInstance;
        } else {
            newInstance.loading = true;
            newInstance.self_panel = newInstance;
            newInstance.self_jif = new JInternalFrame(newInstance.name, true, true, true, true);
            newInstance.self_panel.init();
            self_panel_map.put(newInstanceClass, newInstance);
            return newInstance;
        }
    }

    public void setVisible() {

        self_jif.add(self_panel);
        self_jif.pack();
        self_jif.setVisible(true);
        desktopPane.add(self_jif);
        centerJIF();
        try {
            self_jif.setSelected(true);
        } catch (PropertyVetoException e) {
            handleError(e);
        }
        loading = false;
    }

    private static void handleError(Exception e) {
        e.printStackTrace();
    }

    public void centerJIF() {
        Dimension desktopSize = desktopPane.getSize();
        Dimension JInternalFrameSize = self_jif.getSize();
        int width = (desktopSize.width - JInternalFrameSize.width) / 2;
        int height = (desktopSize.height - JInternalFrameSize.height) / 2;
        self_jif.setLocation(width, height);
    }
}
.

Вот пример кода, который будет реализовать его:

public static void main(String[] args) {
    JFrame jf = new JFrame("MainFrame");
    JDesktopPane jdp = new JDesktopPane();
    jf.setExtendedState( jf.getExtendedState()|JFrame.MAXIMIZED_BOTH );

    VPanel.installDesktopPane(jdp); // This only needs to happen once throughout the entire application lifecycle.

    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("Panels");
    JMenuItem menuItem = new JMenuItem("Open Test Panel");
    menuItem.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            Test_VPanel.showPanel(new Test_VPanel()); // Every time you show the panel, you create a new instance.
            // But this new instance is only used if it is needed. The init() method is only called if it is going
            // To show a new instance.
        }
    });
    menu.add(menuItem);
    menuBar.add(menu);
    jf.setJMenuBar(menuBar);


    jf.setContentPane(jdp);

    jf.setVisible(true);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

static class Test_VPanel extends VPanel {

    public Test_VPanel() {
        super("Test Panel");
    }

    @Override
    public void init() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        JLabel label = new JLabel("JLabel");
        JTextField textField = new JTextField();

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        gbc.gridwidth = 1;
        gbc.gridy = 0;
        gbc.insets = new Insets(4,4,4,4);
        add(label, gbc);

        gbc.gridy = 1;
        add(textField, gbc);

        setVisible(); // This needs to be called at the end of init()
    }
}
.

Мне никогда не понадобится метод вызова, чтобы сделать что-либо с новым экземпляром, но просто вставлять, JPanel возвращает используемый экземпляр, будь то старый экземпляр или новый экземпляр. Итак, если вам нужно что-то сделать с экземпляром, вы сделаете это:

Test_VPanel panel = Test_VPanel.showPanel(new Test_VPanel());
panel.something();
...
.

Жизнь была намного легче для меня, когда я решил пойти по этому маршруту с Singleton Jifs. Настоятельно рекомендуется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top