0

How do I get the text of two JLabels when copying JLabel's text with TransferHandler?

Label1111111 How can I keep the text of both JLabels when copied to Label2222222.

For this reason, I will take control of two Jlabel's texts. This shape can only get the text of JLabel, which was first held. Thank you in advance for your help.

public class deneme2 extends JFrame {

    private static final int COPY = 0;
    private static final int NONE = 0;
    private JPanel contentPane;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    deneme2 frame = new deneme2();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public deneme2() {      
        JPanel panel= new JPanel();
        MouseListener listener = new DragMouseAdapter();    

        JLabel label1 = new JLabel("Label1111111", JLabel.CENTER);        
        handlerLabel(label1);
        label1.addMouseListener(listener);
        panel.add(label1);

        JLabel label2 = new JLabel("Label2222222", JLabel.CENTER);
        handlerLabel(label2);   
        label2.addMouseListener(listener);   
        panel.add(label2);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));

        contentPane.add(panel);
        setContentPane(contentPane);
    }

    private void handlerLabel (JLabel lbl)
    {
         lbl.setTransferHandler(new TransferHandler("text") {
                @Override
                protected void exportDone(JComponent source, Transferable data, int action) {
                    if (action == COPY){
                        ((JLabel)lbl.getDropTarget().getDropTargetContext().getComponent()).getText();
                        //((JLabel) source).setText("LabelEmpty");                                      
                        }
                }             
            });
    }

    private class DragMouseAdapter extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            JComponent comp = (JComponent)e.getSource();
            TransferHandler handler = comp.getTransferHandler();
            handler.exportAsDrag(comp, e, TransferHandler.COPY);   
        }          
    }   
}
MeHcKeR
  • 3
  • 4

1 Answers1

0

Maybe in this way. I added inner class MyLabel and console output in your handlerLabel. Ctrl+v this under your main. It will print to console the original String property of each MyLabels.

    public class MyLabel extends JLabel {
        String original;

        public MyLabel (String text)
        {
            super(text);
            this.original=text;
        }

        public String getOriginal() {
            return original;
        }

        public void setOriginal(String original) {
            this.original = original;
        }

    }
    public deneme2() {      
        JPanel panel= new JPanel();
        MouseListener listener = (MouseListener) new DragMouseAdapter();    

        MyLabel label1 = new MyLabel("Label1111111");        
        handlerLabel(label1);
        label1.addMouseListener(listener);
        panel.add(label1);

        MyLabel label2 = new MyLabel("Label2222222");
        handlerLabel(label2);   
        label2.addMouseListener(listener);   
        panel.add(label2);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));

        contentPane.add(panel);
        setContentPane(contentPane);
    }

        private void handlerLabel(MyLabel lbl) {
        lbl.setTransferHandler(new TransferHandler("text") {
            @Override
            protected void exportDone(JComponent source, Transferable data, int action) {
                if (action == COPY) {
                    System.out.println(((MyLabel) lbl.getDropTarget().getDropTargetContext().getComponent()).getOriginal());
                }
            }
        });
    }

Edit: check this out. Ctrl+V this under your main. It will print to console text of source label and text of target label, also the original property. Class MyLabel implements DropTargetListener , which is then registered by new DropTarget(this, this). Then we define what will happen in overriden drop method.

 public class MyLabel extends JLabel implements DropTargetListener {

        String original;

        public MyLabel(String text) {
            super(text);
            this.original = text;

            new DropTarget(this, this);

            this.setTransferHandler(new TransferHandler("text"));

            final MouseListener listener = new MouseAdapter() {
                @Override
                public void mousePressed(final MouseEvent me) {
                    final MyLabel label = (MyLabel) me.getSource();
                    final TransferHandler handler = label.getTransferHandler();
                    handler.exportAsDrag(label, me, TransferHandler.COPY);
                }
            };

            this.addMouseListener(listener);
        }

        public String getOriginal() {
            return original;
        }

        public void setOriginal(String original) {
            this.original = original;
        }

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {

        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {

        }

        @Override
        public void dropActionChanged(DropTargetDragEvent dtde) {

        }

        @Override
        public void dragExit(DropTargetEvent dte) {

        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            try {
                final String sourceString = (String) dtde.getTransferable().getTransferData(new DataFlavor("application/x-java-jvm-local-objectref; class=java.lang.String"));
                System.out.println("Source: " + sourceString + " target: " + this.getText());
                this.setText(sourceString);
                System.out.println("Original target: "+this.getOriginal());
            } catch (final UnsupportedFlavorException | IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    }

    public deneme2() {
        JPanel panel = new JPanel();
        MyLabel label1 = new MyLabel("Label1111111a");
        panel.add(label1);

        MyLabel label2 = new MyLabel("Label2222222b");
        panel.add(label2);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));

        contentPane.add(panel);
        setContentPane(contentPane);
    }
}

EDIT2: Following code generates this result see result at the end of this answer:Label111111

or

label2222222

It also prints original property to console. Those could be organised differently (MyLabel, MyLabelTransferable, MyLabelDropTargetListener, MyLabelTransferHandler classes, just to give an idea for future refactoring) but it works in this way too. Consider it a quickfix for your use case.

So main class is this:

 public class Deneme2 extends JFrame {

    private static final int COPY = 0;
    private static final int NONE = 0;

    public static void main(String[] args) {
      Deneme2 mainFrame = new Deneme2();
      SwingUtilities.invokeLater(() -> {//let's get that frame on EDT rollin lambda style:)
          mainFrame.setVisible(true);
      });

    }

    public Deneme2() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        MyLabel label1 = new MyLabel("Label1111111a");
        panel.add(label1, BorderLayout.WEST);

        MyLabel label2 = new MyLabel("Label2222222b");
        panel.add(label2, BorderLayout.EAST);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(100, 100, 450, 300);

        panel.setBorder(new EmptyBorder(5, 5, 5, 5));
        this.add(panel);
    }
}

Then MyLabel.java :

    public class MyLabel extends JLabel implements DropTargetListener, Transferable {

    String original;
    protected static final DataFlavor MYLABEL_DATA_FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + "; class=\"" + MyLabel.class.getCanonicalName() + "\"",
             "MyLabel label");
    protected static final DataFlavor[] SUPPORTED_FLAVORS = {MYLABEL_DATA_FLAVOR};

    public MyLabel(String text) {
        super(text);
        this.original = text;
        new DropTarget(this, this);
        this.setTransferHandler(new MyLabelTransferHandler()); //here we use our custom TransferHandler
        final MouseListener listener = new MouseAdapter() {
            @Override
            public void mousePressed(final MouseEvent me) {
                final MyLabel label = (MyLabel) me.getSource();
                final TransferHandler handler = label.getTransferHandler();
                handler.exportAsDrag(label, me, TransferHandler.COPY);
            }
        };
        this.addMouseListener(listener);

    }

    public String getOriginal() {
        return original;
    }

    public void setOriginal(String original) {
        this.original = original;
    }

    @Override
    public void dragEnter(DropTargetDragEvent dtde) {
        if (dtde.getTransferable().isDataFlavorSupported(MyLabel.MYLABEL_DATA_FLAVOR)) {
            System.out.println("Drop accept - MyLabel");
            dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
        } else {
            dtde.rejectDrag();
        }
    }

    @Override
    public void dragOver(DropTargetDragEvent dtde) {
        //System.out.println("Drag over");
    }

    @Override
    public void dropActionChanged(DropTargetDragEvent dtde) {
        System.out.println("Action changed");
    }

    @Override
    public void dragExit(DropTargetEvent dte) {
        System.out.println("Exited");

    }

    @Override
    public void drop(DropTargetDropEvent dtde) {
        System.out.println("Drop detected");

        if (dtde.getTransferable().isDataFlavorSupported(MyLabel.MYLABEL_DATA_FLAVOR)) {
            Transferable t = dtde.getTransferable();

            if (t.isDataFlavorSupported(MyLabel.MYLABEL_DATA_FLAVOR)) {
                try {
                    Object transferData = t.getTransferData(MyLabel.MYLABEL_DATA_FLAVOR);

                    if (transferData instanceof MyLabel) {
                        MyLabel mySourceLabel = (MyLabel) transferData;

                        if (!(mySourceLabel.equals(this))) {
                            dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                            this.setText(mySourceLabel.getText());
                            mySourceLabel.setText("Empty");
                            System.out.println(mySourceLabel.getOriginal() + " " + this.getOriginal());
                        } else {
                            dtde.rejectDrop();
                            System.out.println("Drop rejected - the same MyLabel");
                        }
                    } else {
                        dtde.rejectDrop();
                    }
                } catch (UnsupportedFlavorException | IOException ex) {
                    dtde.rejectDrop();
                }
            } else {
                dtde.rejectDrop();
            }
        }
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return SUPPORTED_FLAVORS;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavor.equals(MYLABEL_DATA_FLAVOR) || flavor.equals(DataFlavor.stringFlavor);

    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        if (flavor.equals(MYLABEL_DATA_FLAVOR)) {
            return this;
        } else if (flavor.equals(DataFlavor.stringFlavor)) {
            return this.getText();
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
    }
}

And then MyLabelTransferHandler.java :

public class MyLabelTransferHandler extends TransferHandler {

    @Override
    public boolean canImport(TransferHandler.TransferSupport support) {
        return (support.getComponent() instanceof MyLabel) && support.isDataFlavorSupported(MyLabel.MYLABEL_DATA_FLAVOR);
    }

    @Override
    public boolean importData(JComponent src, Transferable transferable) {
        return src instanceof MyLabel;
    }

    @Override
    public int getSourceActions(JComponent c) {
        return DnDConstants.ACTION_COPY;
    }

    @Override
    protected Transferable createTransferable(JComponent c) {
        Transferable t = (MyLabel)c;
        return t;
    }

    @Override
    protected void exportDone(JComponent source, Transferable data, int action) {
        System.out.println("Export done.");
    }
}

After final edit result looks like this:

final result

Little clarification:

protected static final DataFlavor MYLABEL_DATA_FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + "; class=\"" + MyLabel.class.getCanonicalName() + "\"",
             "MyLabel label");

in MyLabel. That's important line. This will make getTransferData() return the same instance of MyLabel. If you would do it like:

protected static final DataFlavor MYLABEL_DATA_FLAVOR = new DataFlavor(MyLabel.class, "MyLabel label");

you won't be able to change mySourceLabel text to "Empty" in overridden drop() method, since you would be given a copy of that object.

Also Why shouldn't you extend JFrame and other components? . And you can provide checking for "Empty" text (if getText() returns "Empty", then don't change text in target MyLabel).

  • Thank you for your answer. But when I drag Label11111, I need to get the value in Label22222 and check it. I can not get Label22222 in this way. If you could help with this situation, I would greatly appreciate it. – MeHcKeR Jun 06 '17 at 08:56
  • So when I drag Label1111 I need to getText () in Label2222 to check it. – MeHcKeR Jun 06 '17 at 08:57
  • I can not thank you enough. Thank you so much. Finally, let me ask you something else. How can I make the source 'empty' after dragging? – MeHcKeR Jun 07 '17 at 13:00
  • @MeHcKeR well, that's a little more complicated. We need to obtain `MyLabel` from `getTransferData`, and to do that we need to create `DataFlavor` for `MyLabel`, extend `TransferHandler` and make `MyLabel `implement `Transferable`. In 15min I will update my answer. –  Jun 07 '17 at 14:03
  • Thank you so much. You're gorgeous. I integrated the project. I was confused, I would have solved this problem without you. – MeHcKeR Jun 08 '17 at 14:13