与多线程、泛型等不同,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都可以使背景变黄,鼠标悬停在上面一段时间会显示说明文字。
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)!