与多线程、泛型等不同,swing主要在于使用。
下面主要放代码和注释,少说话。
所有继承JFrame的类都要有一个开始的框架来包含他们,这里直接给出框架,以下几点中不会重复书写。
package Event;import java.awt.*;import javax.swing.*;/**
*
* @author QuinnNorris
* 共用代码
*/public class BaseFrame {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 开启一个线程,所有的Swing组件必须由事件分派线程进行配置,线程将鼠标点击和按键控制转移到用户接口组件。
EventQueue.invokeLater(new Runnable() {
// 匿名内部类,是一个Runnable接口的实例,实现了run方法
public void run() {
JFrame frame = new *********();
// 将*号的地方换成你实现的JFrame的子类,来实现你的代码
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
// 将窗口最大化
frame.setTitle("Christmas");
// 设置窗口标题
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 选择当用户关闭框架的时候进行的操作 ,在有些时候需要将窗口隐藏,不能直接退出需要用到这个方法
frame.setVisible(true);
// 将窗口可见化,这样以便用户在第一次看见窗口之前我们能够向其中添加内容
}
});
}
}输出结果:得到一个基本的公用框架,以后的内容可以在其他类中书写,放入这个框架中。
package Event;import java.awt.*;import javax.swing.*;import java.awt.event.*;/**
*
* @author QuinnNorris 按钮事件
*/public class ButtonFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ButtonFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // 设置默认宽度和高度
buttonPanel = new JPanel(); // 将类的实例域中的JPanel面板对象实例化
makeButton("yellow",Color.YELLOW);
makeButton("blue",Color.BLUE);
makeButton("red",Color.RED); //调用makeButton方法来创建并添加按钮
add(buttonPanel); // 我们将这个添加好按钮的面板添加到原框架中
} /**
* 通过方法来创建按钮,并且完成关联监视器和添加入面板的操作
* @param name 创建按钮的标识
* @param backgroundColor 点击按钮后改变的颜色,匿名内部类只能访问final修饰的变量,所以要用final
*/
public void makeButton(String name,final Color backgroundColor){
JButton colorButton = new JButton(name);
//通过不同的标识名,我们创建按钮
buttonPanel.add(colorButton);
//我们将创建的按钮添加到面板中
//匿名内部类,创建一个ActionListener的实例
colorButton.addActionListener(new ActionListener(){
/**
* 当按钮点击的时候,会自动的调用actionPerformed方法
*/
public void actionPerformed(ActionEvent event) {
buttonPanel.setBackground(backgroundColor);
// 调用setBackground方法,设置背景颜色
}
});
}
}输出结果:在一个全屏窗口中,上方有三个不同颜色的按钮,按下去后,背景颜色会随之改变。
package Event;import java.awt.*;import javax.swing.*;import java.awt.event.*;/**
*
* @author QuinnNorris 更换主题
*/public class MetalFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public MetalFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // 设置默认宽度和高度
buttonPanel = new JPanel(); // 将类的实例域中的JPanel面板对象实例化
UIManager.LookAndFeelInfo[] infos = UIManager
.getInstalledLookAndFeels(); // 调用这个静态方法,我们获得所有主题
makeButton(infos); // 调用makeButton方法来将主题实现
add(buttonPanel); // 我们将这个添加好按钮的面板添加到原框架中
} /**
* 通过方法来创建所有的主题按钮,并且将他们关联监视器
*
* @param infos
* 包含有所有类型主题的数组
*/
private void makeButton(final UIManager.LookAndFeelInfo[] infos) {
for (UIManager.LookAndFeelInfo info : infos) {
JButton button = new JButton(info.getName());
// 用for-each循环来遍历所有的主题
final UIManager.LookAndFeelInfo innerInfo = info;
// 将info复制并且定义位final类型,便于内部类的使用
buttonPanel.add(button);
// 我们将创建的按钮添加到面板中
// 匿名内部类,创建一个ActionListener的实例
button.addActionListener(new ActionListener() {
/**
* 当按钮点击的时候,会自动的调用actionPerformed方法
*/
public void actionPerformed(ActionEvent ae) {
try {
UIManager.setLookAndFeel(innerInfo.getClassName());
// 调用setLookAndFeel方法,更改主题
SwingUtilities.updateComponentTreeUI(buttonPanel);
// 通过这个静态方法,将更改的主题立即应用
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
}输出结果:窗口上方有五个主题按钮,分别写着他们各自主题的名字,点击后会立即更改所属主题。
package Event;import javax.swing.*;import java.awt.*;import java.awt.event.*;/**
*
* @author QuinnNorris 按钮与击键动作
*/public class ActionFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ActionFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// 设置默认宽度和高度
buttonPanel = new JPanel();
// 将类的实例域中的JPanel面板对象实例化
Action yellowAction = new ColorAction("Yellow", Color.YELLOW);
// 创建一个自己定义的ColorAction对象yellowAction
buttonPanel.add(new JButton(yellowAction));
// 创建一个按钮,其属性从所提供的 Action中获取
add(buttonPanel);
// 我们将这个添加好按钮的面板添加到原框架中
InputMap imap = buttonPanel
.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// 我们将JPanel对象的InputMap设置为第二种输入映射,并创建该对象
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
// 在imap中通过调用击键类KeyStroke的静态方法设置击键输入ctrl+Y的组合
// 第二个参数是一个标志参数,将这对参数用键值对的形式存入imap
ActionMap amap = buttonPanel.getActionMap();
// 我们不能将InputMap直接和Action做映射,我们需要用ActionMap做过渡
// 用JPanel中的getACtionMap方法获得amap对象
amap.put("panel.yellow", yellowAction);
// 将imap中标记参数对应的击键组合和相应的Action组合起来
} public class ColorAction extends AbstractAction {
/**
* ColorAction的构造器,存放键值对
* @param name 按钮的名称
* @param c 按钮对应点击后显示的颜色
*/
public ColorAction(String name, Color c) {
putValue(Action.NAME, name);
putValue(Action.SHORT_DESCRIPTION,
"Set panel color to " + name.toLowerCase());
putValue("color", c);
//在构造器中设置一些键值对映射,这些设置的属性将会被JPanel读取
}
/**
* 当按钮点击或击键的时候,会自动的调用actionPerformed方法
*/
public void actionPerformed(ActionEvent event) {
Color c = (Color) getValue("color");
buttonPanel.setBackground(c);
// 调用setBackground方法,设置背景颜色
}
}
}输出结果:窗口上方有yellow按钮,通过点击或者ctrl+Y都可以使背景变黄,鼠标悬停在上面一段时间会显示说明文字。
立即学习“Java免费学习笔记(深入)”;
package Event;import javax.swing.*;/**
*
* @author QuinnNorris
* 继承JFrame的子类,将Component对象内容打包
*/public class MouseFrame extends JFrame{
public MouseFrame(){
add(new MouseComponent());
//向框架中添加一个JComponent的实例
pack();
}
}package Event;import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;/**
*
* @author QuinnNorris 鼠标点击
*/public class MouseComponent extends JComponent {
private static final int SIDELENGTH = 100;
// 定义创造的正方形的边长
private ArrayList<Rectangle2D> squares;
// 声明一个正方形集合
private Rectangle2D current;
// java类库中用来描述矩形的类,它的对象可以看作是一个矩形
/**
* 构造器方法,做初始化工作
*/
public MouseComponent() {
squares = new ArrayList<>();
current = null;
addMouseListener(new MouseHandler());
// 添加一个我们实现的类,这个类继承了监测鼠标点击情况的MouseListener
addMouseMotionListener(new MouseMotionHandler());
// 添加另一个实现类,这个类继承了监测鼠标移动情况的MouseMotionListener
} /**
* 我们覆盖了这个以用来打印图形,将会被自动调用
*
* @param g
* Graphics是我们要使用的2D的一个父类
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// 转换为我们需要使用的类型
for (Rectangle2D r : squares)
g2.draw(r);
// 对数组中的每个正方形,都进行绘制
} /**
* 判断在这个坐标上是否有图形
*
* @param p
* 一对当前的x,y的坐标值
* @return 返回存在的图形或者null
*/
public Rectangle2D find(Point2D p) {
for (Rectangle2D r : squares) {
if (r.contains(p))
//contains方法测定坐标是否在图形的边界内
return r;
}
// 如果在squares这个数组中有这个位置的坐标,表明这个位置上非空
// 返回这个位置上的对象
return null;
// 否则如果什么都没有,返回null
}
/**
* 在这个坐标位置增加一个图形
* @param p 坐标位置
*/
public void add(Point2D p) {
double x = p.getX();
double y = p.getY();
//获取x和y的坐标
current = new Rectangle2D.Double(x - SIDELENGTH / 2,
y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
//用获得的坐标和既定的边长构建一个新的正方形,并将其赋值给current
squares.add(current);
//将current添加到squares队列中
repaint();
//重绘图像
} /**
* 将这个位置的图形移除
* @param s 代表所要移除的矩形对象
*/
public void remove(Rectangle2D s) {
if (s == null)
return;
//如果要移除的内容为空,直接返回
if (s == current)
current = null;
//如果要移除的内容和current正指向的内容相同,则将current清空
//避免发生不必要的错误
squares.remove(s);
//将s从squares的列表中直接删去
repaint();
//重绘图像
}
/**
*
* @author QuinnNorris 继承了MouseAdapter类的鼠标点击控制类
*/
private class MouseHandler extends MouseAdapter {
/**
* 单击鼠标操作
*/
public void mousePressed(MouseEvent event) {
current = find(event.getPoint());
// 将鼠标单击的这个点的坐标的对象赋给current
if (current == null)
//如果这个点没有对象,当前指向空的位置
add(event.getPoint());
//在这个点绘制正方形
}
/**
* 鼠标双击操作
*/
public void mouseClicked(MouseEvent event) {
current = find(event.getPoint());
// 将鼠标单击的这个点的坐标的对象赋给current
if (current != null && event.getClickCount() >= 2)
//如果这个点有对象,而且点击鼠标的次数大于2
remove(current);
//移除current
}
}
/**
*
* @author QuinnNorris
* 鼠标移动拖动类
*/
private class MouseMotionHandler implements MouseMotionListener {
/**
* 鼠标光标移动到组件上,但未按下时调用
*/
public void mouseMoved(MouseEvent event) {
if (find(event.getPoint()) == null)
//如果鼠标所在位置不是空
setCursor(Cursor.getDefaultCursor());
//则将光标的图像设置为默认的图像
else
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
//如果当前位置有图像,则将光标样式设置为手型
} /**
* 鼠标光标在组件上按下,并拖动时调用
*/
public void mouseDragged(MouseEvent event) {
if (current != null) {
//因为在调用这个方法之前肯定会调用点击鼠标的方法
//所以我们直接判断:如果现在current不为空
int x = event.getX();
int y = event.getY();
//获取到坐标
current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2,
SIDELENGTH, SIDELENGTH);
//最后在鼠标放下时进行图形绘制
repaint();
//重绘图像
}
}
}
}输出结果:在这个窗体中,单击一次鼠标会创建一个100像素为边长的小正方形。在正方形内,双击或更多次点击会删除这个正方形。可以点住正方形并进行拖动,并且在指示正方形区域内时,鼠标指针变为手型指针。
与多线程、泛型等不同,swing主要在于使用。
下面主要放代码和注释,少说话。
以上就是java图形化Swing教程(二)的内容,更多相关内容请关注PHP中文网(www.php.cn)!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号