From window, to wind

趣味のゲームとJavaプログラムなどについて 適当に書き綴るブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JDeskTopPaneを用いた透過フレームの仕立て方

JDesktopPaneとJInternalFrameを用いて透過フレームを作りました。
透過フレームには画像のJLabelを入れ、画像の透過もできるようになっています。
またJColorChooserと前に作ったSimpleOptionPaneを用いて背景色の変更を行うダイアログも作製しました。


ImageFrame.png

ColorChooserDialog.png

ソースコード
MainFrameクラス

package program;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;

public class MainFrame extends JFrame{

    private JMenuBar jmb;
    private JMenu jm;
    private JMenuItem jmi1;
    private JPanel jp1, jp2;
    private JDesktopPane jdp1;
    private File file;
    private BufferedImage viewimg;
    private ArrayList<ImageFrame> imgf = new ArrayList<ImageFrame>();
    private int framevalue = 0;
    private Color bgcolor = Color.white;
    private JButton colorb;
    private JScrollPane jsp;
   
    MainFrame(String title){
        super(title);
       
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                String[] obj = {"このプログラムを終了してもよろしいですか?"};
                int retValue = JOptionPane.showConfirmDialog(getContentPane(), obj,
                        "終了の確認",JOptionPane.OK_CANCEL_OPTION);
                if(retValue==JOptionPane.OK_OPTION) {
                    System.exit(0);
                }else if(retValue==JOptionPane.CANCEL_OPTION) {
                    setDefaultCloseOperation(
                            WindowConstants.DO_NOTHING_ON_CLOSE);
                }else if(retValue==JOptionPane.CLOSED_OPTION) {
                    setDefaultCloseOperation(
                            WindowConstants.DO_NOTHING_ON_CLOSE);
                }
            }
        });
       
        jmb = new JMenuBar();
        this.setJMenuBar(jmb);
        jm = new JMenu("File");
        jmi1 = new JMenuItem("画像の読み込み");
        jmi1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                read();
            }
        });
       
        jmb.add(jm);
        jm.add(jmi1);
       
        jp1 = new JPanel();
        jp2 = new JPanel();
        jp2.setPreferredSize(new Dimension(350,800));
       
        jdp1 = new JDesktopPane();
        jdp1.setBackground(bgcolor);
       
        colorb = new JButton("背景色の変更");
        colorb.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                CustomColorChooser ccc = new CustomColorChooser(null, "背景色の変更", true,
                        jdp1, bgcolor);
                int ccc_action =ccc.showOptionPane();
                if(ccc_action==ccc.Yes_value){
                    bgcolor=ccc.getColor();
                    jdp1.setBackground(bgcolor);
                }else{
                    jdp1.setBackground(bgcolor);
                }
            }
        });
       
        jsp = new JScrollPane(jp2);
       
        GBLayout.addGB(colorb,jp1,0,0,1,1);
        GBLayout.addGB(jsp, jp1, 0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        GBLayout.addGB(jp1, getContentPane(), 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        GBLayout.addGB(jdp1, getContentPane(), 1, 0, 1, 1, 4.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
       
        setBounds(10, 10, 600, 400);
        setVisible(true);
    }
   
    private void read(){
        file = ReadImage.readfile(this);
        if(file!=null){
            try {
                viewimg = ImageIO.read(file);
                imgf.add(new ImageFrame(file.getName(),viewimg));
                jdp1.add(imgf.get(framevalue));
                GBLayout.addGB(imgf.get(framevalue).getFileName(), jp2, 0, framevalue, 1, 1);
                GBLayout.addGB(imgf.get(framevalue).getArufaSlider(), jp2, 1, framevalue, 1, 1);
                framevalue++;
                jp2.updateUI();//jp2にコンポーネントを追加したことを適用する。
            } catch (IOException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
        }
    }
}



ImageFrameクラス

package program;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.Hashtable;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicInternalFrameUI;

public class ImageFrame extends JInternalFrame{

    private JLabel jl1;
    private MovePanel mp;
    private JPanel jp;
    private JSlider js;
    ImageFrame(String filename, BufferedImage image){
        mp = new MovePanel(this,image,filename);
       
        jl1 = new JLabel(filename);
       
        js = new JSlider(0, 100, 100);
        js.setPreferredSize(new Dimension(150,50));
        js.setMajorTickSpacing(25);
        Hashtable<Integer, JComponent> table = new Hashtable<Integer, JComponent>();
        table.put(new Integer(0), new JLabel("0%"));
        table.put(new Integer(25), new JLabel("25%"));
        table.put(new Integer(50), new JLabel("50%"));
        table.put(new Integer(75), new JLabel("75%"));
        table.put(new Integer(100), new JLabel("100%"));
        js.setLabelTable(table);
        js.setPaintTicks(true);
        js.setSnapToTicks(true);
        js.setPaintLabels(true);
        js.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                mp.setArufa(js.getValue());
                mp.repaint();
            }
        });
       
        //透明なJPanelをContentPaneと設定します。
        jp = new JPanel();
        jp.setOpaque(false);
        this.setContentPane(jp);
       
        this.getContentPane().add(mp);
        BasicInternalFrameUI ui = (BasicInternalFrameUI)this.getUI();
        ui.setNorthPane(null);
        this.setBorder(BorderFactory.createEmptyBorder());
       
        pack();
        setVisible(true);
    }
   
    public JLabel getFileName(){
        return(jl1);
    }
   
    public JSlider getArufaSlider(){
        return(js);
    }
}



MovePanelクラス

package program;

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;

import javax.swing.JLabel;

public class MovePanel extends JLabel
   implements MouseListener, MouseMotionListener{

    private Point pnow,p0,p1;
    private ImageFrame window;
    private BufferedImage image, nowimg;
    private float arufa =1.0f;
   
    MovePanel(ImageFrame window, BufferedImage image, String filename){
        this.window=window;
        this.image=image;
        setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
        addMouseListener((MouseListener) this);
        addMouseMotionListener((MouseMotionListener) this);
        setToolTipText(filename);
       
    }
   
    public void paint(Graphics g){
        if (image != null) {
            Graphics2D g2d = (Graphics2D)g;
           
            AlphaComposite ac =
                AlphaComposite.getInstance(AlphaComposite.SRC_OVER, arufa);
           
            g2d.setComposite(ac);
            nowimg = image.getSubimage(0, 0, image.getWidth(), image.getHeight());

            g2d.drawImage(nowimg,0,0,this);
        }
    }
   
    public void setArufa(int percent){
        arufa = percent/100f;
    }
   
    public void mouseExited(MouseEvent me) {   
    }

    public void mousePressed(MouseEvent me) {
        p0=me.getPoint();   
    }

    public void mouseReleased(MouseEvent me) {
    }

    public void mouseDragged(MouseEvent me) {
        p1=me.getPoint();
        pnow=window.getLocation();
        window.setLocation(pnow.x+p1.x-p0.x,pnow.y+p1.y-p0.y);
    }

    public void mouseMoved(MouseEvent me) {   
    }

    public void mouseClicked(MouseEvent arg0) {   
    }

    public void mouseEntered(MouseEvent arg0) {   
    }


}



ReadImageクラス

package program;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ReadImage {
   
    private static BufferedImage readimg;
   
    public static BufferedImage read(Component parent){
        try{
            ReadFilechooser rfc = new ReadFilechooser();
            int result = rfc.showOpenDialog(parent);
            File file = rfc.getSelectedFile();
            if(result == JFileChooser.APPROVE_OPTION){
                try{
                    readimg = ImageIO.read(file);
                }catch(IOException e) {
                    // TODO 自動生成された catch ブロック
                    e.printStackTrace();
                }
            }
        }catch(IllegalArgumentException e){
            System.out.println(e);
        }
        return(readimg);
    }
   
    public static File readfile(Component parent){
        File file = null;
        try{
            ReadFilechooser rfc = new ReadFilechooser();
            int result = rfc.showOpenDialog(parent);
           
            if(result == JFileChooser.APPROVE_OPTION){
                file = rfc.getSelectedFile();
            }
        }catch(IllegalArgumentException e){
            System.out.println(e);
        }
        return(file);
    }
}

class ReadFilechooser extends JFileChooser{

    FileNameExtensionFilter filter1,filter2,filter3,filter4;
   
    ReadFilechooser(){
        this.setAcceptAllFileFilterUsed(false);
        this.setAccessory(new ImagePreview(this));
       
        filter1 = new FileNameExtensionFilter("JPEGファイル(*.jpg, *.jpeg)", "jpg", "jpeg");
        addChoosableFileFilter(filter1);
        filter2 = new FileNameExtensionFilter("BMPファイル(*.bmp)", "bmp");
        addChoosableFileFilter(filter2);
        filter3 = new FileNameExtensionFilter("GIFファイル(*.gif)", "gif");
        addChoosableFileFilter(filter3);
        filter4 = new FileNameExtensionFilter("PNGファイル(*.png)", "png");
        addChoosableFileFilter(filter4);
    }
   
    public static void createAndShowGUI() {
        try{
            UIManager.getInstalledLookAndFeels();UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            UIManager.put("FileChooser.readOnly", Boolean.TRUE);
        }catch(Exception e) {
            throw new InternalError(e.toString());
        }
       
    }
}

class ImagePreview extends JComponent
implements PropertyChangeListener {
    private static final int PREVIEW_WIDTH  = 200;
    private static final int PREVIEW_MARGIN = 5;
    private ImageIcon thumbnail = null;
    private File file = null;
    public ImagePreview(JFileChooser fc) {
        setPreferredSize(new Dimension(PREVIEW_WIDTH+PREVIEW_MARGIN*2, 50));
        fc.addPropertyChangeListener(this);
    }
    public void loadImage() {
        if(file == null) {
            thumbnail = null;
            return;
        }
        ImageIcon tmpIcon = new ImageIcon(file.getPath());
        if(tmpIcon == null) return;
        if(tmpIcon.getIconWidth()>PREVIEW_WIDTH) {
            Image img = tmpIcon.getImage().getScaledInstance(PREVIEW_WIDTH,-1,Image.SCALE_DEFAULT);
            thumbnail = new ImageIcon(img);
        }else{
            thumbnail = tmpIcon;
        }
    }
    public void propertyChange(PropertyChangeEvent e) {
        boolean update = false;
        String prop = e.getPropertyName();
        if(JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
            file = null;
            update = true;
        }else if(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
            file = (File)e.getNewValue();
            update = true;
        }
        if(update) {
            thumbnail = null;
            if(isShowing()) {
                loadImage();
                repaint();
            }
        }
    }
    protected void paintComponent(Graphics g) {
        if(thumbnail==null) {
            loadImage();
        }
        if(thumbnail!=null) {
            int x = getWidth()/2  - thumbnail.getIconWidth()/2;
            int y = getHeight()/2 - thumbnail.getIconHeight()/2;
            if(y < 0)              y = 0;
            if(x < PREVIEW_MARGIN) x = PREVIEW_MARGIN;
            thumbnail.paintIcon(this, g, x, y);
        }
    }
}



CustomColorChooserクラス

package program;

import java.awt.Color;
import java.awt.Frame;

import javax.swing.JColorChooser;
import javax.swing.JDesktopPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class CustomColorChooser extends SimpleOptionPane{

    private JColorChooser jcc;
    private JDesktopPane jdp;
    CustomColorChooser(Frame owner, String title, boolean modal,
            JDesktopPane jdp1, Color bgcolor){
        super(owner,title,modal);
        this.jdp = jdp1;
        jcc = new JColorChooser(bgcolor);
        jcc.getSelectionModel().addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent ce) {
                jdp.setBackground(jcc.getColor());
            }
        });
        GBLayout.addGB(jcc, getComponentPane(), 0, 0, 1, 1);
        this.pack();
    }
   
    public Color getColor(){
        return(jcc.getColor());
    }
}



あと他にメインクラスやGBLayoutクラスやSimpleOptionPaneクラスを用いていますが省略しています。

プログラムの解説
通常JFrameなどではContentPaneなどがあり、JFrameを透明にすることはできません。
しかしながらJInternalFrameではContentPaneをsetOpaque(false)で透明にしたJPanelを代入することによりJInternalFrameを透明にすることができます。
今回は画像ファイルを取得することにより以前に作成したJFrameをドラッグで移動することのできるMovePanelのpaintメソッドで画像を表示しています。この画像の透過度を変更するJSliderをImageFrameに用意しておき、呼び出し元のMainFrameに配置するようにしています。
またJDesktopPaneの背景色をJColorChooserと前に作ったSimpleOptionPaneを用いて変更するようにしました。JColorChooserにchangelistenerを加え、色の変更を適用しています。またキャンセルするときは初期の色を設定することで元に戻しています。
課題点としてはJInternalFrameの順番をどこかで管理できる用にするところです。
ソースコードを全て示しているので見ずらいと思いますがご容赦ください。
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://kagenyan.blog69.fc2.com/tb.php/31-410a403f
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。