我开发了一种小型摆动应用,其中上半部分有一个方形旋转,下半部分有一个按钮,可以停止/运行方形旋转。
我使用GridLayout
放置旋转方块和按钮。
(另一种方法是使用2 JPanel
s,一个使用旋转方形,第二个包含按钮。使用此按钮会显示正确的大小。)
以下是代码: -
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Rotation {
JButton jbtn=new JButton("Stop");
component jpn2=new component(); //created a JPanel named jpn2 and got a reference to its timer object.
Timer timer=jpn2.timer;
Rotation()
{
JFrame jfrm=new JFrame("Rotating a square about a center");
jfrm.setSize(400,400);
jfrm.setLayout(new GridLayout(2,1));
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel jpnl=new JPanel();
//jpnl.add(jbtn);
jbtn.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Stop"))
{
timer.stop();
jbtn.setText("Spin");
}
if(e.getActionCommand().equals("Spin"))
{
timer.start();
jbtn.setText("Stop");
}
}});
jfrm.add(jpn2);
jfrm.add(jbtn);
//jfrm.add(new JButton("Click"));
jfrm.setVisible(true);
//jfrm.setOpacity(0.8f);
}
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
{
//JFrame.setDefaultLookAndFeelDecorated(true);
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.invokeLater(new Runnable(){public void run(){new Rotation();}});
}
}
class component extends JPanel implements ActionListener
{
Timer timer;
int theta=0;
component()
{
timer=new Timer(10,this);
timer.start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
g2.rotate(theta,100,100);
g2.fillRect(50, 50, 100,100);
}
public void actionPerformed(ActionEvent e)
{
//Changing a global variable and then drawing the rectangle again and hence indirectly the square rotates.
theta=theta+10;
if(theta==360)
theta=0;
repaint();
}
}
这是输出: -
但我的困惑是当我决定使用FlowLayout
代替GridLayout
时,我只获得了按钮而没有旋转方块。
据我所知,FlowLayout
将组件放在一行中,如果空间小于它则使用多行。
任何人都可以解决我目前无法解决的这个小愚蠢的问题。
答案 0 :(得分:3)
您的问题是您使用setSize(...)
这些布局将完全按照您的要求进行操作 - 将GUI的大小设置为该大小,无论一切都没有显示。一般情况下,您希望避免调用setSize(...)
,而是在必要时让组件覆盖getPreferredSize()
并在显示它之前打包GUI,让组件自行调整大小。请注意,FlowLayout有其用途,但与其他布局相比,它不是一堆中最“最聪明”的布局(在我看来)。
答案 1 :(得分:3)
FlowLayout
仅接受来自其中PreferredSize
的孩子,JComponents
无法继续使用其父级
GridLayout
(您的问题)从最大和更宽的PreferredSize
获取JComponents
,并为容器中的其余Dimmension
设置相同的JComponents
, JComponents
可以调整大小,并且可以与父级
必须对LayoutManager
使用pre_implemented JFrame
,使用Borderlayout
,JComponents
可以调整大小并连续使用它(仅限CENTER区域,仅使用其中一个坐标)
除去
jfrm.setLayout(new GridLayout(2,1));
并改变
jfrm.add(jpn2);
jfrm.add(jbtn, BorderLayout.SOUTH);
JFrame
frm.add(jpn2); equals frm.add(jpn2, BorderLayout.CENTER);
答案 2 :(得分:2)
正如其他人所说(+1到mKorbel和HFOE)
问题是您使用setSize(..)
而是在将pack()
设置为可见之前调用JFrame
。
您还必须覆盖getPrefferedSize(..)
类中的JPanel
,它将返回您的方块的大小乘以2(否则当它旋转时它不适合)。
在旁注中不要在main(..)
中抛出任何重要的事情。
请参阅下面的代码(使用FlowLayout
,但也适用于GridLayout
):
使用new FlowLayout()
:
使用new GridLayout(2,1)
:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Rotation {
JButton jbtn = new JButton("Stop");
component jpn2 = new component(); //created a JPanel named jpn2 and got a reference to its timer object.
Timer timer = jpn2.timer;
Rotation() {
JFrame jfrm = new JFrame("Rotating a square about a center");
// jfrm.setLayout(new FlowLayout());
jfrm.setLayout(new GridLayout(2, 1));
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jbtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Stop")) {
timer.stop();
jbtn.setText("Spin");
}
if (e.getActionCommand().equals("Spin")) {
timer.start();
jbtn.setText("Stop");
}
}
});
jfrm.add(jpn2);
jfrm.add(jbtn);
jfrm.pack();
jfrm.setVisible(true);
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Rotation();
}
});
}
}
class component extends JPanel implements ActionListener {
Timer timer;
int theta = 0;
int width = 100, height = 100;
component() {
timer = new Timer(10, this);
timer.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(theta, 100, 100);
g2.fillRect(50, 50, width, height);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width * 2, height * 2);//multiply by 2 to fit while rotating
}
@Override
public void actionPerformed(ActionEvent e) {
//Changing a global variable and then drawing the rectangle again and hence indirectly the square rotates.
theta = theta + 10;
if (theta == 360) {
theta = 0;
}
repaint();
}
}