java 图形化界面笔记(1)

目录


JFrame窗体................................................................................................. 1

 


* 方法颜色

* 小节颜色

* 引起注意

 

一、JFrame  窗体

  • 创建窗体
    在开发Java应用程序时,通常情况下利用JFrame创建窗口。利用JFrame创建的窗口分别包含一个标题、最小化按钮、最大化按钮和关闭按钮

    在利用JFrame创建窗口时,需要设置单击关闭按钮时执行的动作 ,设置方法为通过JFrame对象的setDefault CloseOperation(int operation)方法,该方法的入口参数可以从JFrame类的静态常量中选择,可选的静态常量(代码的下方)

    public class Test(){
        public static void main(String[] args){
            JFrame frame = new JFrame(“新的窗口”);      // 新建一个窗体,窗体的标题是“”中的内容,
            JPanel panel = new JPanel();             // Jpanel 是面板容器类,包含在swing中;
            JTextArea textArea = new JTextArea();     //  JTextArea  文本区, JTextField文本框 
            
            panel.setLayout(new GridLayout());        // Layout是布局; GridLayout 网格型布局
            textArea.setText("test");
            //当TextArea里的内容过长时生成滚动条
            panel.add(new JScrollPane(textArea));
            frame.add(panel);                       //在新建的窗体中添加面板;
            
            frame.setSize(200,200);                  //设置窗体的尺寸
            frame.setVisible(true);                  //注意这一步一定要最后调用,使得这个窗体可见,false是不可见;
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); //定义了点击关闭按钮的作用; } }

    setDefaultCloseOperation(int operation):设置用户在此窗体上发起 "close" 时默认执行的操作。方法中的参数解释如下:

     为“0”或DO_NOTHING_ON_CLOSE:

    (在 WindowConstants 中定义):不执行任何操作;要求程序在已注册的WindowListener 对象的 windowClosing 方法中处理该操作。

    比如实例程序代码中更改为f.setDefaultCloseOperation(f. DO_NOTHING_ON_CLOSE);或者f.setDefaultCloseOperation(0),然后查看效果,可以发现窗口无法关闭,下面是相同测试方法,不再解释了。

     为“1”或HIDE_ON_CLOSE

    调用任意已注册的 WindowListener 对象后自动隐藏该窗体。此时没有关闭程序,只是将程序界面隐藏了。可以打开任务管理器,可以看到一个叫“java.exe”的进程(如果调试运行了多个java程序,则会看到多个“java.exe”的进程),如果此时用EditPlus测试程序,会发现当单击窗口的关闭按钮关闭窗口后,却无法再次对程序进行调试,因为程序线程没有关闭,在任务管理器中关闭java.exe(如果有多个“java.exe”的进程,则先都关闭掉,再来测试该问题)基础后,EditPlus才可以重新编译改程序。

    为“2”或DISPOSE_ON_CLOSE

    调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。但继续运行应用程序,释放了窗体中占用的资源。

     为“3”EXIT_ON_CLOSE(在 JFrame 中定义):使用 System exit 方法退出应用程序。仅在应用程序中使用。结束了应用程序。

    默认情况下,该值被设置为 HIDE_ON_CLOSE。

    当注释掉实例中的f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);语句时,起到的效果和f.setDefaultCloseOperation(f. HIDE_ON_CLOSE); 或者f.setDefaultCloseOperation(1);一样。


  • JFrame窗口的默认显示位置为从(0,0)点开始绘制,即从显示器的左上角开始绘制。通常情况下更希望显示在显示器的中央,可以通过Toolkit类 的静态方法getDefaultToolkit()获得一个Toolkit类的对象,然后通过Toolkit对象的getScreenSize()方法获 得一个Dimension类的对象,通过Dimension对象可以得到显示器的大小,例如显示器的宽度和高度,获得Dimension对象的典型代码如 下:
    Dimension displaySize = Toolkit.getDefaultToolkit().getScreenSize();
    通过JFrame对象的getSize()方法也可以得到一个Dimension类的对象,通过Dimension对象可以得到JFrame窗口的大小,例如JFrame窗口的宽度和高度,获得Dimension对象的典型代码如下:
    Dimension frameSize = frame.getSize();
    利用上面得到的两个Dimension类的对象,就可以计算出显示在显示器中央时的起始绘制点了,然后通过JFrame对象的setLocation(int x, int y)方法,设置JFrame窗口在显示器中的起始绘制点,典型代码如下:
    frame.setLocation((displaySize.width - frameSize.width) / 2,(displaySize.height - frameSize.height) / 2);
    利用JFrame创建的窗口默认是不可见的,即在运行时不在显示器上绘制窗口,设置为可见的方法是通过JFrame对象的setVisible(boolean b)方法,并将入口参数设为true,典型代码如下:
    frame.setVisible(true): 
  • 修改图标 

          

   setIconImage (Toolkit . getDefaultToolkit (). createImage (
                    getClass (). getResource ("login.png" )));
     (注意:图片login.png要放在与调用该图片的类于同一个文件夹;另,Java好像不支持ico格式)
  • Java Swing如何实时刷新JTextArea,以显示刚才加append的内容 

    在代码中执行完textArea.append("message")后,如果你想让这个更新立刻显示在界面上而不是等swing的主线程返回后刷新,我们一般会在该语句后调用textArea.invalidate()和textArea.repaint()。

   问题是这个方法并不能有任何效果,textArea的内容没有任何变化,这或许是swing的一个bug,有一个笨拙的办法可以实现这个效果,就是执行以下语句

     textArea.paintImmediately(textArea.getBounds());

     或
     textArea.paintImmediately(textArea.getX(), textArea.getY(), textArea.getWidth(), textArea.getHeight());

   这时,你会发现你刚才增加的消息已经被实时地显示出来了。

  • 画图并添加鼠标事件
    final Image img = Toolkit.getDefaultToolkit().getImage(Test.class.getResource("map.png"));
            JTextArea ta = new JTextArea() {             //文本区;
                {
                    setOpaque(false);// 设置不透明的参数,缺少时背景图片不显示
                }
    
                public void paint(Graphics g) {
                    g.drawImage(img, 0, 0, this);
                    super.paint(g);
                }
            };
    
            MouseListener ml = new MouseListener() {                    //鼠标监听器;
                public void mouseClicked(MouseEvent e) {                //MouseEvent 是鼠标活动类型,
                    if (e.getClickCount() == 2) {                       // GetClickCount() 鼠标点击的次数统计;
                        System.out.println("Mouse double clicked");
                                      }
                            }
                          public void mouseEntered(MouseEvent e) {
                    // TODO Auto-generated method stub
    
                }
    
                public void mouseExited(MouseEvent e) {
                    // TODO Auto-generated method stub
    
                }
    
                public void mousePressed(MouseEvent e) {
                    // TODO Auto-generated method stub
    
                }
    
                public void mouseReleased(MouseEvent e) {
                    // TODO Auto-generated method stub
    
                }
                   };
            ta.addMouseListener(ml);
            ta.setBounds(0, 0, 300, 200);
            ta.setEditable(false);

     

  • 在一个TextArea里写内容,其他两个同时显示
    /*JTextArea是多行文本编辑器,JTextField是一个简单的单行文本编辑器,它们都由JTextComponent类派生,所以它们包含一些共同的方法,如设置和获取所显示的文本,指定文本是否可编辑,或者是否只读,管理文本内的光标位置以及管理文本选择等。
    文本组件的模型是一个称为Document的对象,对于一个JTextArea或JTextField,要为之增加或删除文本,就会改变相应的Document。当出现某种改动时,要由文档本身(而不是可视的组件)来生成与文本相关的事件。因此,为了接收JTextArea修改的通知,就要向底层Document注册,而不是向JTextArea组件本身注册:
    */
    JTextArea textArea = new JTextArea();
    Document d = textArea.getDocument();
    d.addDocumentListener(someListener);
    /*
    一个例子如下,在任意的一个文本区中键入的内容,在三个区中都将得以体现。我们要做的就是让所有的文本区都共享一个数据模型。
    */
    import java.awt.Container;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    
    public class ShareModel {
       
        public static void main(String[] args) {
            JFrame frame = new JFrame("ShareModel");
           
            JTextArea areaFiftyOne = new JTextArea();
            JTextArea areaFiftyTwo = new JTextArea();
            areaFiftyTwo.setDocument(areaFiftyOne.getDocument());
            JTextArea areaFiftyThree = new JTextArea();
            areaFiftyThree.setDocument(areaFiftyOne.getDocument());
           
            Container content = frame.getContentPane();                 //获得Jframe的所有awt组件,在一个容器里;这个可以用于导入到其它的容器里,实现一个一模一样的界面;
            content.setLayout(new GridLayout(3,1));                     //利用刚刚获得的窗体格式创建一个网格布局;
            content.add(new JScrollPane(areaFiftyOne));
            content.add(new JScrollPane(areaFiftyTwo));
            content.add(new JScrollPane(areaFiftyThree));
           
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(300,300);
            frame.setVisible(true);
        }
    }
    /*
    在一个文本区中键入时,此文本区将接受键盘事件,它会调用文档中的方法来更新数据,相应的,文档会向其它文本区发送事件,通知出现了更新,从而使它们能够正确的显示文档的新数据。不过,所有这一切都无需我们关心。要做的只是通知文本区使用同一数据。Swing会接管其余的一切。
    另外需要注意的,JTextArea没有滚动功能,超出文本区域的内容无法显示出来,通过鼠标拖动也无法看到。但它实现了Swing Scrollable接口。必须把它放置在JScrollPane的内部才能实现滚动。
    */

     

  • Jframe其它方法;
    常用方法
    protected void addImpl(Component comp, Object constraints, int index)   添加指定的子 Component。
    protected JRootPane createRootPane()                                    由构造方法调用,以创建默认的 rootPane。
    protected void frameInit()                                             由构造方法调用,以适当地初始化 JFrame。
    AccessibleContext getAccessibleContext()                                获得与此 JFrame 关联的 AccessibleContext。
    Container getContentPane()                                              返回此窗体的 contentPane 对象
    int getDefaultCloseOperation()                                          返回用户在此窗体上发起 "close" 时执行的操作。
    Component getGlassPane()                                                返回此窗体的 glassPane 对象。
    Graphics getGraphics()                                                  为组件创建一个图形上下文。
    JMenuBar getJMenuBar()                                                  返回此窗体上设置的菜单栏。
    JLayeredPane getLayeredPane()                                           返回此窗体的 layeredPane 对象。
    JRootPane getRootPane()                                                 返回此窗体的 rootPane 对象。
    TransferHandler getTransferHandler()                                    获取 transferHandler 属性。
    static boolean isDefaultLookAndFeelDecorated()                          如果新创建的 JFrame 应该由当前外观为其提供 Window 装饰,则返回 trueprotected boolean isRootPaneCheckingEnabled()                           返回是否将对 add 和 setLayout 的调用转发到 contentPane。
    protected String paramString()                                          返回此 JFrame 的字符串表示形式。
    protected void processWindowEvent(WindowEvent e)                        处理此组件上发生的窗口事件。
    void remove(Component comp)                                             从该容器中移除指定组件。
    void repaint(long time, int x, int y, int width, int height)            在 time 毫秒内重绘此组件的指定矩形区域。
    void setContentPane(Container contentPane)                              设置 contentPane 属性。
    void setDefaultCloseOperation(int operation)                            设置用户在此窗体上发起 "close" 时默认执行的操作。
    static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated)
    提供一个关于新创建的 JFrame 是否应该具有当前外观为其提供的 Window 装饰(如边框、关闭窗口的小部件、标题等等)的提示。
    void setGlassPane(Component glassPane) 设置 glassPane 属性。 void setIconImage(Image image) 设置要作为此窗口图标显示的图像。 void setJMenuBar(JMenuBar menubar) 设置此窗体的菜单栏。 void setLayeredPane(JLayeredPane layeredPane) 设置 layeredPane 属性。 void setLayout(LayoutManager manager) 设置 LayoutManager。 protected void setRootPane(JRootPane root) 设置 rootPane 属性。 protected void setRootPaneCheckingEnabled(boolean enabled) 设置是否将对 add 和 setLayout 的调用转发到 contentPane。 voidsetTransferHandler(TransferHandler newHandler) 设置 transferHandler 属性,该属性是支持向此组件传输数据的机制。 void update(Graphics g) 只是调用 paint(g)。

     

 

 

二、Timer计时器

  • timer使用
    private java.util.Timer timer;
    timer = new Timer(true);
    timer.schedule(
    new java.util.TimerTask() { public void run()
    { //server.checkNewMail(); 要操作的方法} }, 0, 5*60*1000);
    第一个参数是要操作的方法,
    第二个参数是要设定延迟的时间,
    第三个参数是周期的设定,每隔多长时间执行该操作。
    使用这几行代码之后,Timer本身会每隔5分钟调用一遍
    server.checkNewMail()方法,不需要自己启动线程。Timer本身也是多线程同
    步的,多个线程可以共用一个Timer,不需要外部的同步代码。
    
    timer方法 (
    1)Timer.schedule(TimerTask task,Date time) 安排在指定的时间执行指定的任务。 (2)Timer.schedule(TimerTask task,Date firstTime ,long period) 安排指定的任务在指定的时间开始进行重复的固定延迟执行. (3)Timer.schedule(TimerTask task,long delay) 安排在指定延迟后执行指定的任务. (4)Timer.schedule(TimerTask task,long delay,long period) 安排指定的任务从指定的延迟后开始进行重复的固定延迟执行. (5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period) 安排指定的任务在指定的时间开始进行重复的固定速率执行. (6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period) 安排指定的任务在指定的延迟后开始进行重复的固定速率执行.

     

  • timer注意事项
    ava.util这个包中可以找到Timer和TimerTask这两个类。Timer直接从Object继承,它相当于一个计时器,能够用它来指定某个时间来执行一项任务,或者每隔一定时间间隔反复执行同一个任务。创建一个Timer后,就会生成一个线程在背后运行,来控制任务的执行。而TimerTask就是用来实现某项任务的类,它实现了Runnable接口,因此相当于一个线程。
    如何实现自己的任务调度?
    1、继承TimerTask,注意TimerTask是实现Runnable接口的,因此只要重载run()方法即可。
    2、创建Timer对象,调用schedule()方法。相关注意点分析:
    1、任务调度要优先考虑实时保证
    由于Java的天性,并且在开发JDK的过程中要考虑到不同平台,而不同平台的线程调度机制是不同的,因此各种平台下JVM 的线程调度机制也是不一致的。从而Timer不能保证任务在所指定的时间内执行。另外由于Time rTask是实现Runnable接口的,在TimerTask被放进线程队列睡眠一段时间(wait)之后,当到了指定的该唤起该TimerTask时,由于执行的确切时机取决于JVM的调度策略和当前还有多少线程在等待CPU处理。因此 就不能保证任务在所指定的时间内执行。通常在如下两种情况下导致任务延迟执行:
    (1)、有大量线程在等待执行
    (2)、GC机制的影响导致延迟
    这也是为什么在Timer API中存在两组调度方法的原因。即:
    (1)、schedule()
    用固定延迟调度。使用本方法时,在任务执行中的每一个延迟会传播到后续的任务的执行。
    (2)、scheduleAsFixedRate()
    用固定比率调度。使用本方法时,所有后续执行根据初始执行的时间进行调度,从而希望减小延迟。
    具体使用哪一个方法取决于哪些参数对你的程序或系统更重要。
    2、每个Timer对象要在后台启动一个线程。这种性质在一些托管的环境下不推荐使用,比如在应用服务器中。因为这些线程不在容器的控制范围之内了。

     

 

posted on 2016-06-01 22:19  bai_yan  阅读(3072)  评论(0编辑  收藏  举报

导航