2013-11-04 46 views
1

我創建了一個8x8 GridLayout棋盤遊戲,其中每個網格中都有一個不透明的按鈕。我創建了以8x8表格的形式顯示,當用戶點擊任何單元格時,它應該執行一些操作。現在,網格的樣子:在Swing中重新定位GridLayout

enter image description here

我希望它通過動畫重新定位這一個角度看是這樣的:

enter image description here

是否有可能做到這一點在Swing使用repaint?如果沒有,是否有更好的工具包可以使用,除了Swing以便我可以製作動畫?

+1

這樣做現場組件上,不是真的,通過繪畫做,絕對... – MadProgrammer

回答

3

更改直播組件的狀態需要更多的則只是畫...

例如,基於Boann的例子...

enter image description here

繪畫在Swing是一個複雜和優化過程,並不總是以線性方式完成。

話雖如此,有一種方法,但你需要爲它工作。

enter image description here

這是基於JXLayer API和pbjar例子

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import org.jdesktop.jxlayer.JXLayer; 
import org.pbjar.jxlayer.demo.TransformUtils; 
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel; 

public class Twister02 { 

    public static void main(String[] args) { 
     new Twister02(); 
    } 

    public Twister02() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new ExamplePane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class ExamplePane extends JPanel { 

     private JSlider slider; 
     private FieldPane fieldPane; 
     private DefaultTransformModel transformModel; 

     public ExamplePane() { 

      setLayout(new BorderLayout()); 

      slider = new JSlider(0, 360); 
      slider.setValue(0); 
      slider.addChangeListener(new ChangeListener() { 
       @Override 
       public void stateChanged(ChangeEvent e) { 

        transformModel.setRotation(Math.toRadians(slider.getValue())); 

       } 
      }); 

      fieldPane = new FieldPane(); 

      transformModel = new DefaultTransformModel(); 
      transformModel.setRotation(Math.toRadians(0)); 
      transformModel.setScaleToPreferredSize(true); 
      JXLayer<JComponent> rotatePane = TransformUtils.createTransformJXLayer(fieldPane, transformModel); 

      add(slider, BorderLayout.NORTH); 
      add(rotatePane); 

     } 
    } 

    public class FieldPane extends JPanel { 

     public FieldPane() { 
      setLayout(new GridLayout(8, 8)); 
      for (int i = 0; i < 64; i++) { 
       add(new JButton("" + i)); 
      } 
     } 

    } 
} 

現在的問題是,在pbjar例子似乎已經消失了互聯網的面貌,我們非常失望。

但是,你可以從here

搶副本添加,因爲它的樂趣......

enter image description here

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import org.jdesktop.jxlayer.JXLayer; 
import org.pbjar.jxlayer.demo.TransformUtils; 
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel; 

public class Twister02 { 

    public static void main(String[] args) { 
     new Twister02(); 
    } 

    public Twister02() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new ExamplePane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class ExamplePane extends JPanel { 

     private JSlider rotateSlider; 
     private JSlider shearXSlider; 
     private JSlider shearYSlider; 
     private FieldPane fieldPane; 
     private DefaultTransformModel transformModel; 

     public ExamplePane() { 

      setLayout(new BorderLayout()); 

      rotateSlider = new JSlider(0, 180); 
      rotateSlider.setValue(0); 
      rotateSlider.addChangeListener(new ChangeListener() { 
       @Override 
       public void stateChanged(ChangeEvent e) { 

        transformModel.setRotation(Math.toRadians(rotateSlider.getValue())); 

       } 
      }); 
      shearXSlider = new JSlider(-100, 100); 
      shearXSlider.setValue(0); 
      shearXSlider.addChangeListener(new ChangeListener() { 
       @Override 
       public void stateChanged(ChangeEvent e) { 

        double value = shearXSlider.getValue()/200d; 
        transformModel.setShearX(value); 

       } 
      }); 
      shearYSlider = new JSlider(-100, 100); 
      shearYSlider.setValue(0); 
      shearYSlider.addChangeListener(new ChangeListener() { 
       @Override 
       public void stateChanged(ChangeEvent e) { 

        double value = shearYSlider.getValue()/200d; 
        transformModel.setShearY(value); 

       } 
      }); 

      fieldPane = new FieldPane(); 

      transformModel = new DefaultTransformModel(); 
      transformModel.setRotation(Math.toRadians(0)); 
      transformModel.setScaleToPreferredSize(true); 
      JXLayer<JComponent> rotatePane = TransformUtils.createTransformJXLayer(fieldPane, transformModel); 

      JPanel sliders = new JPanel(new GridLayout(3, 0)); 
      sliders.add(rotateSlider); 
      sliders.add(shearXSlider); 
      sliders.add(shearYSlider); 

      add(sliders, BorderLayout.NORTH); 
      add(rotatePane); 

     } 
    } 

    public class FieldPane extends JPanel { 

     public FieldPane() { 
      setLayout(new GridLayout(8, 8)); 
      for (int i = 0; i < 64; i++) { 
       add(new JButton("" + i)); 
      } 
     } 

    } 
} 
+0

我沒有注意到您的第一個gif中顯示的問題,因爲Nimbus L&F似乎沒有受到它的影響(雖然它仍然不是*完全正確)。 +1,儘管如此,我很佩服你把它放在一起的速度。 – Boann

+0

@Boann有一些東西在鋪設,玩弄想法 – MadProgrammer

+0

@MadProgrammer,從我看到這個問題的那一刻起,我正在桌子上敲着我的頭,問「名字是什麼,名字是什麼,我在哪裏看到這樣的實現,它在java.net或swingxlab中的某處「但我記不起我近一年前看過的是哪一個:謝謝你再次提醒我:) +1 – Sage

0

是否有可能在Swing中使用repaint執行此操作?如果沒有,是否有更好的工具包可以使用,而不是Swing,這樣我就可以製作這個動畫了?

不,這不可能與GridLayout。在JPanel上使用圖形drawLine並使用Timer對其進行動畫處理。

+0

謝謝!會試試看! – Mercenary

1

重寫容器的paintChildren方法將轉換應用於Graphics對象,然後使用它調用super.paintChildren

JFrame frame = new JFrame(); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
JPanel panel = new JPanel(new GridLayout(8, 8)) { 
    @Override 
    public void paintChildren(Graphics g1) { 
     Graphics2D g = (Graphics2D)g1; 
     g.rotate(0.3, getWidth()/2, getHeight()/2); 
     super.paintChildren(g); 
    } 
}; 
frame.add(panel); 
for (int i = 0; i < 64; i++) panel.add(new JButton("" + i)); 

frame.pack(); 
frame.setVisible(true); 

它(前/後)看起來像什麼:

enter image description here

編輯:雖然看起來聰明,你不能在旋轉的按鈕,網格有點繞其中心簡單的例子實際上點擊這些按鈕在他們的旋轉位置;可能使用AffineTransform對象來轉換鼠標事件並將它們重定向到正確的兒童正確的組件,但我沒有嘗試過。重繪區域也可能存在問題。 ......也許繪製自己的網格(@ Masud的答案)可以避免試圖在Swing之上破解這個功能。

+0

有趣的做法。 +1 –

+0

現在做鼠標點擊 – MadProgrammer

+0

並在屏幕上運行鼠標;) – MadProgrammer