2013-08-25 63 views
2

我可以對面板進行交換,但它不夠好。例如,如果panel1碰撞panel2,它會交換,但如果碰撞panel3,panel3也移動到panel1位置(我不想發生這種情況)。如果有大約10個面板,並且如果我想用panel10交換panel1,那麼使用當前的邏輯是不可能的。任何人都可以請幫助我。在JPanels數組中交換JPanels

下面是上述邏輯的代碼:

import javax.swing.border.LineBorder; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class GDragAndDrop extends JFrame { 
    public GDragAndDrop() { 
     add(new op()); 
    } 

    public static void main(String[] args) { 
     GDragAndDrop frame = new GDragAndDrop(); 
     frame.setTitle("GDragAndDrop"); 
     frame.setSize(600, 600); 
     frame.setLocationRelativeTo(null);// Center the frame 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

class op extends JPanel implements MouseListener, MouseMotionListener { 
    JPanel p; 
    Point pPoint; 
    Point p1; 
    Point p2; 
    MouseEvent pressed; 
    JPanel[] panels = new JPanel[3]; 

    public op() { 
     int b = 3; 
     int a = 0; 
     for (int i = 0; i < b; i++) { 
     panels[i] = new JPanel(); 
     panels[i].setBackground(Color.cyan); 
     panels[i].setBorder(new LineBorder(Color.black)); 
     a = a + 20; 
     panels[i].setPreferredSize(new Dimension(a, 400)); 
     panels[i].addMouseListener(this); 
     panels[i].addMouseMotionListener(this); 
     panels[i].setBorder(new LineBorder(Color.black)); 
     panels[i].setVisible(true); 
     panels[i].add("Center", new JLabel("To Move" + i)); 
     this.add(panels[i]); 
     } 
    } 

    public JPanel getPanelColliding(JPanel dragPanel) { 
     Rectangle rDrag = dragPanel.getBounds(); 
     for (int i = 0; i < 3; i++) { 
     if (panels[i] == dragPanel) 
      continue; 
     Rectangle r = panels[i].getBounds(); 
     if (r.intersects(rDrag)) { 
      return panels[i]; 
     } 
     } 
     return null; 
    } 

    public void mousePressed(MouseEvent e) { 
     int b = 3; 
     for (int i = 0; i < b; i++) { 
     if (e.getSource() == panels[i]) { 
      pressed = e; 
      p2 = panels[i].getLocation(); 
     } 
     } 
    } 

    @Override 
    public void mouseDragged(MouseEvent arg0) { 
     int b = 3; 
     for (int i = 0; i < b; i++) { 
     if (arg0.getSource() == panels[i]) { 
      pPoint = panels[i].getLocation(pPoint); 
      int x = pPoint.x - pressed.getX() + arg0.getX(); 
      int y = pPoint.y - pressed.getY() + arg0.getY(); 
      if (getPanelColliding(panels[i]) != null) { 
       JPanel DragP = new JPanel(); 
       DragP = getPanelColliding(panels[i]); 
       p1 = getPanelColliding(panels[i]).getLocation(p1); 
       int x1 = pPoint.x - pressed.getX() + arg0.getX(); 
       int y1 = pPoint.y - pressed.getY() + arg0.getY(); 
       panels[i].setLocation(x1, y1); 
       DragP.setLocation(p2); 
      } else 
       panels[i].setLocation(x, y); 
     } 
     } 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
    } 
} 
+0

這是你的其他非常類似的問題的可能重複[如何交換的JPanel,當碰撞其他的JPanel](http://stackoverflow.com/questions/ 18421055 /如何對換入的JPanel,當-IT-碰撞,另一個-的JPanel)。請解釋一下:這些問題如何不同?爲什麼不應該把這個問題作爲重複來關閉? –

+0

我現在關閉了上一個問題。請幫我解決這個問題。感謝氣墊船充滿了鰻魚的監督。 – Rookie86

回答

2

如果你不想使用拖放和拖放,如果你的JPanels是成列的,然後再考慮這些建議:

  • 我已經得到了這個具有容器的JPanel工作(在一個包含多個列組件)使用FlowLayout
  • 我已將MouseAdapter作爲MouseListener和MouseMotionListener添加到容器JPanel,而不是列組件。
  • 我通過在容器JPanel上調用getComponentAt(mouseEvent.getPoint())獲得了選定的列組件。當然,檢查它不是null。
  • 如果選定的組件不爲空,那麼我用這個組件設置一個selectedComponent變量,並放置一個佔位符JLabel,它具有相同的preferredSize。我通過從容器JPanel中刪除所有組件,然後重新將它們全部重新添加,除了選擇的組件,而我添加佔位符JLabel。然後我調用對容器的重新驗證和重繪。
  • 要拖動所選組件,請將其提升到glassPane(即將其添加到glassPane中)。
  • 使glassPane可見並給它一個空佈局。
  • 只需通過更改玻璃板相對於glassPane的位置,將所選組件簡單地拖放到glassPane中即可。
  • 在mouseReleased上,再次使用getComponentAt(...)找出鼠標結束的列組件。
  • 然後從容器JPanel中刪除所有組件,
  • 然後將它們全部按照所需順序重新添加。
  • 然後再次調用對容器JPanel進行重新驗證和重繪。

例如:

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.GridBagLayout; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.*; 

public class SwapPanelEg extends JPanel { 
    private static final long serialVersionUID = 1594039652438249918L; 
    private static final int PREF_W = 400; 
    private static final int PREF_H = 400; 
    private static final int MAX_COLUMN_PANELS = 8; 
    private JPanel columnPanelsHolder = new JPanel(); 

    public SwapPanelEg() { 
     columnPanelsHolder.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5)); 

     for (int i = 0; i < MAX_COLUMN_PANELS; i++) { 
     int number = i + 1; 
     int width = 20 + i * 3; 
     int height = PREF_H - 30; 
     columnPanelsHolder.add(new ColumnPanel(number, width, height)); 
     } 

     MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
     columnPanelsHolder.addMouseListener(myMouseAdapter); 
     columnPanelsHolder.addMouseMotionListener(myMouseAdapter); 

     setLayout(new GridBagLayout()); 
     add(columnPanelsHolder); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class MyMouseAdapter extends MouseAdapter { 
     private JComponent selectedPanel; 
     private Point deltaLocation; 
     private JLabel placeHolder = new JLabel(); 
     private JComponent glassPane; 

     @Override 
     public void mousePressed(MouseEvent evt) { 
     if (evt.getButton() != MouseEvent.BUTTON1) { 
      return; 
     } 
     JPanel source = (JPanel) evt.getSource(); 
     selectedPanel = (JComponent) source.getComponentAt(evt.getPoint()); 

     if (selectedPanel == null) { 
      return; 
     } 

     if (selectedPanel == source) { 
      selectedPanel = null; 
      return; 
     } 

     glassPane = (JComponent) SwingUtilities.getRootPane(source).getGlassPane(); 
     glassPane.setVisible(true); 
     Point glassPaneOnScreen = glassPane.getLocationOnScreen(); 
     glassPane.setLayout(null); 
     Point ptOnScreen = evt.getLocationOnScreen(); 
     Point panelLocOnScreen = selectedPanel.getLocationOnScreen(); 

     int deltaX = ptOnScreen.x + glassPaneOnScreen.x - panelLocOnScreen.x; 
     int deltaY = ptOnScreen.y + glassPaneOnScreen.y - panelLocOnScreen.y; 

     deltaLocation = new Point(deltaX, deltaY); 

     Component[] allComps = source.getComponents(); 
     for (Component component : allComps) { 
      source.remove(component); 
      if (component == selectedPanel) { 
       placeHolder.setPreferredSize(selectedPanel.getPreferredSize()); 
       source.add(placeHolder); 
       selectedPanel.setSize(selectedPanel.getPreferredSize()); 
       int x = ptOnScreen.x - deltaLocation.x; 
       int y = ptOnScreen.y - deltaLocation.y; 
       selectedPanel.setLocation(x, y); 
       glassPane.add(selectedPanel); 
      } else { 
       source.add(component); 
      } 
     } 
     revalidate(); 
     repaint(); 

     } 

     @Override 
     public void mouseDragged(MouseEvent evt) { 
     if (selectedPanel != null) { 
      Point ptOnScreen = evt.getLocationOnScreen(); 

      int x = ptOnScreen.x - deltaLocation.x; 
      int y = ptOnScreen.y - deltaLocation.y; 
      selectedPanel.setLocation(x, y); 
      repaint(); 
     } 
     } 

     @Override 
     public void mouseReleased(MouseEvent evt) { 
     if (evt.getButton() != MouseEvent.BUTTON1) { 
      return; 
     } 
     if (selectedPanel == null) { 
      return; 
     } 

     JComponent source = (JComponent) evt.getSource(); 

     Component[] allComps = source.getComponents(); 
     Component overComponent = (JComponent) source.getComponentAt(evt 
       .getPoint()); 

     source.removeAll(); 

     if (overComponent != null && overComponent != placeHolder 
       && overComponent != source) { 
      for (Component component : allComps) { 
       if (component == placeHolder) { 
        source.add(overComponent); 
       } else if (component == overComponent) { 
        source.add(selectedPanel); 
       } else { 
        source.add(component); 
       } 
      } 
     } else { 
      for (Component component : allComps) { 
       if (component == placeHolder) { 
        source.add(selectedPanel); 
       } else { 
        source.add(component); 
       } 
      } 
     } 
     revalidate(); 
     repaint(); 
     selectedPanel = null; 
     } 
    } 

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

     JFrame frame = new JFrame("SwapPanelEg"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class ColumnPanel extends JPanel { 
    private static final long serialVersionUID = 5366233209639059032L; 
    private int number; 
    private int prefWidth; 
    private int prefHeight; 

    public ColumnPanel(int number, int prefWidth, int prefHeight) { 
     setName("ColumnPanel " + number); 
     this.number = number; 
     this.prefWidth = prefWidth; 
     this.prefHeight = prefHeight; 

     add(new JLabel(String.valueOf(number))); 
     setBorder(BorderFactory.createLineBorder(Color.black)); 
     setBackground(Color.cyan); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(prefWidth, prefHeight); 
    } 

    public int getNumber() { 
     return number; 
    } 

} 
+0

非常感謝您的氣墊船,這正是我所需要的。很長一段時間以來,我一直在爲這個部分苦苦掙扎。 – Rookie86