私のプログラムでは、ドロップされたオブジェクトにドラッグされたデータを取得しようとすると、すべてのStepPanelを含むパネルに新しいStepPanelを作成するため、プログラムが遅くなります。コードをトレースしたところ、プログラムが遅くなるのはメソッドgetTransferData(DataFlavour df)であることがわかりました。インターネットでその問題を検索したところ、Oracleが提供する解決策を見つけました。ソリューションページには次のように書かれています。
問題:JavaアプリケーションがDnD操作にTransferable.getTransferData()を使用する場合、ドラッグに長い時間がかかるようです。転送されたデータを必要な場合にのみ初期化するために、初期化コードがTransferable.getTransferData()に配置されました。
転送可能なデータの生成にはコストがかかり、DnD操作中にTransferable.getTransferData()が複数回呼び出されるため、速度が低下します。
解決策:転送可能なデータをキャッシュして、1回だけ生成されるようにします。
しかし、転送可能なデータをキャッシュする方法が見つかりませんでした。その問題に苦労したことがある人はいますか?私は本当にその問題でプログラムが遅くなるのを防ぐ必要があります。転送可能なデータをキャッシュする以外に解決策があれば、それを聞いていただければ幸いです。ありがとうございました。
また、StepPanelコード:
public class StepPanel extends JPanel implements Transferable, DragSourceListener, DragGestureListener, DropTargetListener{
private DragSource source;
private TransferHandler transfer;
private DropTarget dropTarget;
StepContainer statementStep;
StepContainerPanel mainPanel;
JButton add;
JButton maximize;
JButton remove;
JTextArea stepCommand;
ImageIcon removeIcon;
ImageIcon maximizeIcon;
ImageIcon addIcon;
JPanel eastPanel;
public StepPanel( StepContainer step) /*throws MalformedURLException*/ {
setLayout( new BorderLayout());
setBackground(Color.WHITE);
statementStep = step;
removeIcon = new ImageIcon( "src/jlfgr-1_0/toolbarButtonGraphics/general/Delete24.gif");
maximizeIcon = new ImageIcon( "src/jlfgr-1_0/toolbarButtonGraphics/general/ZoomIn24.gif");
addIcon = new ImageIcon( "src/jlfgr-1_0/toolbarButtonGraphics/general/Add24.gif");
eastPanel = new JPanel();
add = new JButton( addIcon);
maximize = new JButton( maximizeIcon);
remove = new JButton( removeIcon);
stepCommand = new JTextArea();
stepCommand.setPreferredSize( new Dimension( StepContainer.WIDHT, StepContainer.HEIGHT));
stepCommand.setBorder( BorderFactory.createLineBorder( Color.BLACK));
add.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementStep.addSubStep();
((StepContainerPanel)getParent().getParent().getParent().getParent().getParent()).updateView();
}
});
maximize.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((StepContainerPanel)getParent().getParent().getParent().getParent().getParent()).setStepContainer( statementStep);
((StepContainerPanel)getParent().getParent().getParent().getParent().getParent()).updateView();
}
});
remove.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementStep.removeMe();
((StepContainerPanel)getParent().getParent().getParent().getParent().getParent()).updateView();
}
});
//Setting tool tips to the buttons
maximize.setToolTipText( "Click this button to maximize");
remove.setToolTipText( "Remove this step");
add.setToolTipText( "Add a sub-step");
//East Panel
eastPanel.setLayout( new GridLayout());
eastPanel.add( add);
eastPanel.add( remove);
eastPanel.setBackground( getBackground());
//StepPanel
add( maximize, BorderLayout.WEST);
add( eastPanel, BorderLayout.EAST);
add( stepCommand, BorderLayout.CENTER);
//The Properties for Drag and Drop
//setting transferhandler to the panel
transfer = new TransferHandler() {
@Override
public Transferable createTransferable( JComponent c) {
return new StepPanel( statementStep);
}
};
setTransferHandler( transfer);
source = new DragSource();
source.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, this);
//setting drop data
dropTarget = new DropTarget( this, this);
}
@Override
public void paintComponent( Graphics g) {
super.paintComponent( g);
setBorder( BorderFactory.createTitledBorder(statementStep.getBorderText()));
setToolTipText( statementStep.getBorderText());
}
public JButton getRemove() {
return remove;
}
public StepContainer getStep() {
return statementStep;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{ new DataFlavor( StepPanel.class, "Step")};
}
@Override
public boolean isDataFlavorSupported( DataFlavor df) {
return true;
}
//when this method is called it returns this object
@Override
public Object getTransferData( DataFlavor df) throws UnsupportedFlavorException, IOException {
return this;
}
@Override
public void dragEnter(DragSourceDragEvent dsde) {}
@Override
public void dragOver(DragSourceDragEvent dsde) {}
@Override
public void dropActionChanged(DragSourceDragEvent dsde) {}
@Override
public void dragExit(DragSourceEvent dse) {}
@Override
public void dragDropEnd(DragSourceDropEvent dsde) {}
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
source.startDrag( dge, DragSource.DefaultMoveDrop, this, this);
}
@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) {
//getting the dragged step from dataFlavor and synchroning it if this
//step has same parent with dropped step then change their order
//getting and initalizing dragged step
Transferable transferedPanel = dtde.getTransferable();
DataFlavor[] datas = transferedPanel.getTransferDataFlavors();
try {
//its dragged panel, which is in the 0th index of DataFlavor array
StepPanel draggedPanel = ((StepPanel)transferedPanel.getTransferData( datas[0]));
//since the dragged step will come as if it is different object
//we cannot compare their parents directly since it will give
//wrong comparison. So we look order of parent step of both dragged
//and dropped step
if( statementStep.getParent().getBorderText().equals( draggedPanel.getStep().getParent().getBorderText())) {
StepContainer sameParent = statementStep.getParent();
int indexOfFirstSubStep = statementStep.getParent().getSubSteps().indexOf( statementStep);
int indexOfSecondSubStep = draggedPanel.getStep().getParent().getSubSteps().indexOf( draggedPanel.getStep());
System.out.println( "We ");
sameParent.changeOrders( indexOfFirstSubStep, indexOfSecondSubStep);
}
else {
System.out.println( "We cannot change those steps' orders since their parents are different");
}
} catch (UnsupportedFlavorException ex) {
Logger.getLogger(StepPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(StepPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}