Невозможно перетащить иногда - PullRequest
0 голосов
/ 06 января 2019
package newjframe;


import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.event.MouseInputAdapter;


public class NewJFrame extends javax.swing.JFrame {



public NewJFrame() {
    initComponents();
    setLocationRelativeTo(null);
}

public class Draggable extends JComponent {

    private Point pointPressed;
    private JComponent draggable;

    public Draggable(final JComponent component, final int x, final int y) {
        draggable = component;
        setCursor(new Cursor(Cursor.HAND_CURSOR));
        setLocation(x, y);
        setSize(component.getPreferredSize());
        setLayout(new BorderLayout());
        add(component);
        MouseInputAdapter mouseAdapter = new MouseHandler();
        addMouseMotionListener(mouseAdapter);
        addMouseListener(mouseAdapter);
    }

    public class MouseHandler extends MouseInputAdapter {

        @Override
        public void mouseDragged(final MouseEvent e) {
            Point pointDragged = e.getPoint();
            Point location = getLocation();
            location.translate(pointDragged.x - pointPressed.x,
                    pointDragged.y - pointPressed.y);
            setLocation(location);
        }

        @Override
        public void mousePressed(final MouseEvent e) {
            pointPressed = e.getPoint();
        }
    }
}


@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    panel = new javax.swing.JPanel();
    layer = new javax.swing.JLayeredPane();
    cbb = new javax.swing.JComboBox<>();
    label = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    cbb.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3"}));
    cbb.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            cbbActionPerformed(evt);
        }
    });

    layer.setLayer(cbb, javax.swing.JLayeredPane.DEFAULT_LAYER);
    layer.setLayer(label, javax.swing.JLayeredPane.DEFAULT_LAYER);

    javax.swing.GroupLayout layerLayout = new javax.swing.GroupLayout(layer);
    layer.setLayout(layerLayout);
    layerLayout.setHorizontalGroup(
        layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layerLayout.createSequentialGroup()
            .addGap(41, 41, 41)
            .addComponent(cbb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(129, 129, 129)
            .addComponent(label)
            .addContainerGap(202, Short.MAX_VALUE))
    );
    layerLayout.setVerticalGroup(
        layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layerLayout.createSequentialGroup()
            .addGap(30, 30, 30)
            .addGroup(layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addComponent(label)
                .addComponent(cbb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addContainerGap(329, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
    panel.setLayout(panelLayout);
    panelLayout.setHorizontalGroup(
        panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(layer)
    );
    panelLayout.setVerticalGroup(
        panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(layer)
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

private void cbbActionPerformed(java.awt.event.ActionEvent evt) {                                    
    // TODO add your handling code here:
    int[] xy = {100, 200, 300};
    label.setText("DRAG THIS");
    switch (cbb.getSelectedIndex()) {
        case 0:
            draglabel = new Draggable(label, xy[0], xy[0]);
            layer.add(draglabel);
            break;
        case 1:
            draglabel = new Draggable(label, xy[0], xy[1]);
            layer.add(draglabel);
            break;
        case 2:
            draglabel = new Draggable(label, xy[0], xy[2]);
            layer.add(draglabel);
            break;
        default:
            draglabel = new Draggable(label, xy[0], xy[0]);
            layer.add(draglabel);
    }
}                                   


public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JComboBox<String> cbb;
private javax.swing.JLabel label;
private javax.swing.JLayeredPane layer;
private javax.swing.JPanel panel;
// End of variables declaration                   
Draggable draglabel;
}

Приведенный выше код должен позволять легко перетаскивать Jlabels, но каждый раз, когда они вызываются с помощью actionlistener в JComboBox, их становится все труднее перетаскивать. GIF добавлен для большей ясности https://imgur.com/rPL5ZMC Я пробовал метод repaint () в методе класса и actionlistner, но он не работал

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Я вызвал и создал экземпляр функции drag n drop в конструкторе, а затем использовал label.setLocation (x, y), чтобы решить эту проблему, поскольку JComboBox просто определяет положение меток, мне не нужно иметь экземпляр объекта каждый раз, когда вызывается actionperformed.

0 голосов
/ 06 января 2019

Опять же, я хотел бы упростить попытку уточнить вещи, в том числе:

  • Используйте гораздо более простой MouseListener / MouseAdapter, а не D & D, как вы делали изначально. Вы, кажется, внесли это изменение.
  • Не оборачивать JLabel без необходимости в другой компонент
  • Таким образом, слушатели Mouse будут добавлены непосредственно в JLabel, а не в объект-оболочку.
  • Не изменяет JLayeredPane по умолчанию и уникальный макет
  • Явное удаление старых компонентов перед добавлением новых
  • Вызов repaint() на JLayeredPane после добавления или удаления компонентов.

Например, что-то вроде этого:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;    
import javax.swing.*;

@SuppressWarnings("serial")
public class TestDragging extends JPanel {
    private static final String[] ITEMS = {"Item One", "Item Two", "Item Three"};
    private static final Dimension PREF_SIZE = new Dimension(400, 400);
    private JLabel label;
    private JComboBox<String> comboBox = new JComboBox<>(ITEMS);
    private JLayeredPane layeredPane = new JLayeredPane();

    public TestDragging() {
        comboBox.addActionListener(new ComboListener());
        JPanel topPanel = new JPanel();
        topPanel.add(comboBox);

        layeredPane.setPreferredSize(PREF_SIZE);
        layeredPane.setBorder(BorderFactory.createEtchedBorder());

        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(layeredPane, BorderLayout.CENTER);
    }

    private class ComboListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (label != null) {
                layeredPane.remove(label);
            }

            int index = comboBox.getSelectedIndex();
            int x = 100;
            int y = 100 + 100 * index;
            String text = comboBox.getSelectedItem().toString();
            label = createDraggingLabel(x, y, text);

            layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
            layeredPane.repaint();
        }

        private JLabel createDraggingLabel(int x, int y, String text) {
            JLabel label = new JLabel(text);
            label.setSize(label.getPreferredSize());
            label.setLocation(x, y);

            MyMouse myMouse = new MyMouse();
            label.addMouseListener(myMouse);
            label.addMouseMotionListener(myMouse);
            return label;
        }
    }

    private static void createAndShowGui() {
        TestDragging mainPanel = new TestDragging();

        JFrame frame = new JFrame("Test Dragging");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class MyMouse extends MouseAdapter {
    private Point pointPressed = null;

    @Override
    public void mousePressed(MouseEvent e) {
        pointPressed = e.getPoint();
    } 

    @Override
    public void mouseDragged(MouseEvent e) {
        JLabel label = (JLabel) e.getSource();
        label.setCursor(new Cursor(Cursor.HAND_CURSOR));
        Point pointDragged = e.getPoint();
        Point location = label.getLocation();
        int dx = pointDragged.x - pointPressed.x;
        int dy = pointDragged.y - pointPressed.y;
        location.translate(dx, dy);
        label.setLocation(location);
        Container container = label.getParent();
        container.repaint();
    }
}
...