欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java Swing實現窗體添加背景圖片的2種方法詳解

 更新時間:2017年11月14日 11:25:52   作者:pzy4447  
這篇文章主要介紹了Java Swing實現窗體添加背景圖片的2種方法,結合實例形式較為詳細的分析了Swing實現窗體添加背景圖片的方法,并總結分析了Swing重繪中repaint與updateUI的區(qū)別,需要的朋友可以參考下

本文實例講述了Java Swing實現窗體添加背景圖片的2種方法。分享給大家供大家參考,具體如下:

在美化程序時,常常需要在窗體上添加背景圖片。通過搜索和測試,發(fā)現了2種有效方式。下面分別介紹。

1. 利用JLabel加載圖片

利用JLabel自帶的setIcon(Icon icon)加載icon,并設置JLabel對象的位置和大小使其完全覆蓋窗體。這是一個很取巧的辦法,代碼非常簡單,如下所示。

JLabel lbBg = new JLabel(imageIcon);
lbBg.setBounds(0, 0, frameSize.width, frameSize.height);
this.getContentPane().add(lbBg);

然而這種方法有幾個要注意的點:

(1)不能使用布局管理器

此時你需要將布局管理器設置為null,然后精確控制所有控件的大小和位置。否則,JLabel無法完整覆蓋窗體。

(2)應當先添加背景JLabel,再添加其它控件。否則其它控件將被JLabel所遮擋(為什么不是后添加的遮擋先添加的?)。

(3)由于控件及窗體的尺寸需要手動控制,因此無法對背景圖片進行縮放。

2. 重載JPanel的paintComponent(Graphics g)方法

通過重載該方法,在JPanel的繪制階段將指定圖片繪制上去即可。由于背景是繪制出來的,因此不會對布局有任何影響。

示例代碼如下:

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, d.width, d.height, this);
MainFrame.instance().repaint();
}

下面是一個完整的demo。

package frame;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ImageFrame extends JFrame {
  class ImagePanel extends JPanel {
    Dimension d;
    Image image;
    public ImagePanel(Dimension d, Image image) {
      super();
      this.d = d;
      this.image = image;
    }
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(image, 0, 0, d.width, d.height, this);
      MainFrame.instance().repaint();
    }
  }
  Dimension frameSize = new Dimension(500, 300);
  ImageIcon imageIcon = new ImageIcon(this.getClass().getResource(
      "/images/bg.jpg"));
  public ImageFrame() {
    // 設置窗體屬性
    setSize(frameSize);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setIconImage(imageIcon.getImage());
    setUndecorated(true);
  }
  public void addImageByJLable() {
    setLayout(null);
    // 設置背景
    JLabel lbBg = new JLabel(imageIcon);
    lbBg.setBounds(0, 0, frameSize.width, frameSize.height);
    this.getContentPane().add(lbBg);
    addComponents();
    setVisible(true);
  }
  public void addImageByRepaint() {
    ImagePanel imagePanel = new ImagePanel(frameSize, imageIcon.getImage());
    setContentPane(imagePanel);
    addComponents();
    setVisible(true);
  }
  private void addComponents() {
    JButton btn1 = new JButton("haha");
    btn1.setBounds(10, 20, 60, 30);
    this.getContentPane().add(btn1);
    JTextField jtf = new JTextField("22222222222");
    jtf.setBounds(200, 100, 80, 30);
    this.getContentPane().add(jtf);
  }
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    ImageFrame imageFrame = new ImageFrame();
    // imageFrame.addImageByJLable();
    imageFrame.addImageByRepaint();
  }
}

運行效果如下:

圖1 使用JLabel加載圖片效果

圖1可見,使用JLabel時,由于未圖片尺寸與窗體尺寸不一致,導致圖片只顯示出一部分;且有一個控件被遮擋了。注意:通過精細設置尺寸和添加控件順序,可以達到較為滿意的效果的。

圖2 使用重繪方式加載圖片

圖2可見,不需要可以設置匹配尺寸和控件的添加順序,即可得到比較滿意的效果。

補充說明:Swing 重繪 repaint,updateUI區(qū)別

repaint

public void repaint()重繪此組件。

如果此組件是輕量組件,則此方法會盡快調用此組件的 paint 方法。否則此方法會盡快調用此組件的 update 方法。

注:有關 AWT 和 Swing 所用繪制機制的更多信息,包括如何編寫最高效的繪制代碼的信息 。

updateUI

public void updateUI()UIManager 發(fā)出的關于 L&F 已經更改的通知。用 UIManager 的最新版本替換當前的 UI 對象。覆蓋: 類 JComponent 中的 updateUI另請參見: JComponent.updateUI()

可能大家都試過在swing的事件監(jiān)聽中動態(tài)添加組件,但是JFrame卻不會動態(tài)顯示,只有變大變小(實際是重畫了)才會顯示。repaint,updateUI可以,用validate發(fā)現也可以。

API中對repaint()方法是這樣描述的,調度完當前所有未完成的事件后重新繪制該組件,所以repaint方法不總是馬上執(zhí)行。

package awtDemo;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Ss extends JFrame {
    Container con = this.getContentPane();
    JButton jb1 = new JButton("jb1");
    JButton jb2 = new JButton("jb2");
    JLabel jl1 = new JLabel("jl1");
    FlowLayout gly = new FlowLayout();
    JPanel jp = new JPanel(gly);
    public Ss() {
        con.add(jp);
        jp.add(jb1);
        jp.add(jb2);
        MyListener ml = new MyListener();
        jb1.addMouseListener(ml);
        this.setSize(300, 200);
        this.setVisible(true);
    }
    private class MyListener extends MouseAdapter {
      @Override
      public void mouseClicked(MouseEvent e) {
          // TODO Auto-generated method stub
          try {
              JButton jb3 = new JButton("jb3");
              jp.add(jb3);
//              jp.updateUI();//可以正常顯示
              jp.repaint();//API中對repaint()方法是這樣描述的,調度完當前所有未完成的事件后重新繪制該組件,repaint方法不總是馬上執(zhí)行,所以只有調整大小才可以顯示。
          //主要就是下面的invalidate和validate
          //當然,用jp來invalidate和validatae也是可以的
//                jp.invalidate();
          } catch (Exception ex) {
              ex.printStackTrace();
          }
      }
  }
    public static void main(String s[]) {
      Ss sss = new Ss();
      sss.setVisible(true);
  }
}

swing重繪主要有四個關鍵方法:paint(),repaint(),revalidate(),paintImmediately();

而進行繪制時后它會依次調用update(),paint(),paintComponent(),paintBorder(),paintChildren()進行繪制;

那么repaint()方法為什么會延時呢?

調用repaint()會導致一個區(qū)域被增加到重繪列表隊列中,且被預定重繪。產生一個防止到系統(tǒng)事件隊列中的請求,
一旦該請求被處理,內部工具自動毀掉組件的paintImmediately()方法。然后該方法立即執(zhí)行繪制;

也就是說通常情況下repaint()它是不會立即執(zhí)行的,調用它后會有一個等待處理的過程。但repaint比較高效,會推遲實際的繪制并將多余的請求壓縮到單個 paint 調用中。

所以如何解決它的repaint()延時問題呢?

1.讓它立即執(zhí)行:使用paintImmediately()。

2.使用SwingUtilities工具類中的invokeLater(Runnable doRun)方法;把你要在repaint()后執(zhí)行的操作寫在要執(zhí)行的線程中;(它會把這個方法也加入到java內部事件隊列中,它排在repaint()之后,所以一般情況下,它是等repaint()執(zhí)行完之后才會執(zhí)行,雖然這樣達到效果,但并不理想);

更多關于java相關內容感興趣的讀者可查看本站專題:《Java數據結構與算法教程》、《Java字符與字符串操作技巧總結》、《Java操作DOM節(jié)點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設計有所幫助。

相關文章

  • Java Native關鍵字原理及作用解析

    Java Native關鍵字原理及作用解析

    這篇文章主要介紹了Java Native關鍵字原理及作用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • redis深入淺出分布式鎖實現上篇

    redis深入淺出分布式鎖實現上篇

    在單體應用中,如果我們對共享數據不進行加鎖操作,會出現數據一致性問題,我們的解決辦法通常是加鎖。下面我們一起聊聊使用redis來實現分布式鎖
    2022-08-08
  • SpringBoot項目在IntelliJ IDEA中如何實現熱部署

    SpringBoot項目在IntelliJ IDEA中如何實現熱部署

    spring-boot-devtools是一個為開發(fā)者服務的一個模塊,其中最重要的功能就是自動應用代碼更改到最新的App上面去。,這篇文章主要介紹了SpringBoot項目在IntelliJ IDEA中如何實現熱部署,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Spring中的@Value和@PropertySource注解詳解

    Spring中的@Value和@PropertySource注解詳解

    這篇文章主要介紹了Spring中的@Value和@PropertySource注解詳解,@PropertySource:讀取外部配置文件中的key-value保存到運行的環(huán)境變量中,本文提供了部分實現代碼,需要的朋友可以參考下
    2023-11-11
  • java file.renameTo返回false的原因及解決方案

    java file.renameTo返回false的原因及解決方案

    這篇文章主要介紹了java file.renameTo返回false的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java代理 jdk動態(tài)代理應用案列

    java代理 jdk動態(tài)代理應用案列

    java代理有jdk動態(tài)代理、cglib代理,這里只說下jdk動態(tài)代理,jdk動態(tài)代理主要使用的是java反射機制,需要了解的朋友可以參考下
    2012-11-11
  • Spring Security將用戶數據存儲到數據庫的方法

    Spring Security將用戶數據存儲到數據庫的方法

    這篇文章主要介紹了Spring Security將用戶數據存儲到數據庫的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • SpringMVC @RequestBody的使用解析

    SpringMVC @RequestBody的使用解析

    這篇文章主要介紹了SpringMVC @RequestBody的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java終止線程實例和stop()方法源碼閱讀

    Java終止線程實例和stop()方法源碼閱讀

    這篇文章主要介紹了Java終止線程實例和stop()方法源碼閱讀,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12
  • 關于Shiro過濾器配置方式(ShiroFilterFactoryBean)

    關于Shiro過濾器配置方式(ShiroFilterFactoryBean)

    這篇文章主要介紹了關于Shiro過濾器配置方式(ShiroFilterFactoryBean),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論