2013-08-25 3 views
2

Я могу обменивать панели, но это недостаточно. Например, если панель1 сталкивается с панелью2, она меняет местами, но если та же самая сталкивается с панелью3, панель3 также перемещается в панель1 (что я не хочу делать). Если имеется около 10 панелей, и если я хочу поменять панель1 с панелью 10, это невозможно с текущей логикой. Кто-нибудь может помочь мне.Swap 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-когда-это сталкивается-другой-JPanel). Пожалуйста, объясните: как эти вопросы различны? Почему этот вопрос не должен закрываться как дубликат? –

+0

Я закрыл предыдущий вопрос сейчас. Пожалуйста, помогите мне с этим вопросом. Спасибо Hovercraft Full of Eels для наблюдения. – Rookie86

ответ

2

Если вы не хотите использовать перетащить и падение, и если ваши JPanels в столбцах, а затем рассмотреть эти предложения:

  • Я получил эту работу, имеющий контейнер JPanel (тот, который содержит несколько компонентов столбца) использует FlowLayout
  • Я добавил MouseAdapter как MouseListener и MouseMotionListener в контейнер JPanel, а не компоненты столбца.
  • Я получил выбранный компонент столбца, вызвав getComponentAt(mouseEvent.getPoint()) на контейнер JPanel. Конечно, проверьте, что это не пусто.
  • Если выбранный компонент не является нулевым, то я устанавливаю переменную selectedComponent с этим компонентом и кладу местозаполнитель JLabel, который имеет тот же самый предпочтительный размер на своем месте. Я делаю это, удаляя все компоненты из контейнера JPanel, а затем повторно добавляя их обратно, за исключением выбранного компонента, где вместо этого добавляю placeholder JLabel. Затем я вызываю revalidate и перерисовывают на контейнере.
  • Чтобы перетащить выбранный компонент, поднимите его на стеклянную панель (т. Е. Добавьте ее в стеклянную панель).
  • сделать стеклянную панель видимой и придать ей нулевой макет.
  • Перетащите выбранный компонент в стеклянную панель, просто изменив ее положение относительно стеклопанели.
  • На mouseReleased, выясните, какой компонент столбца находится над мышью, снова используя getComponentAt(...).
  • Затем удалите все компоненты из контейнера JPanel,
  • , а затем добавьте их обратно в нужном порядке.
  • Затем еще раз вызовите revalidate и перерисуйте на контейнере 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

2

Если вы не хотите использовать свинг drag-and-drop, переставляем содержание источника и назначения, как показано в этом JLayeredPaneexample и variation ,

Смежные вопросы