From window, to wind

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

スポンサーサイト

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

マウスホイールで動く二層のパネル

JPanelを拡張したクラスで上のPanelがマウスホイールで動くようにしています。
名前にドラッグが入っているのは、最初ドラッグで移動させようとしたから。
とりあえずはいらないと思ったのでマウスホイールにしました。
実行例
draggedpane.png

下のパネルbottomPanelが赤色でJCheckBoxを配置しており、
上のパネルtopPanelが半透明の青色でJSpinnerを配置しています。
JCheckBoxでホイールで移動できる範囲を制御しており、
JSpinnerでホイールの回転あたりの移動量を調節しています。

ソースコード
フレームクラス
package program;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MainFrame extends JFrame{


JSpinner spinner;
SpinnerNumberModel model;
Dimension d = new Dimension(200,200);
DraggedPane dp;
JCheckBox jcb;

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);
}
}
});


this.setSize(d);

dp = new DraggedPane(d,d.height/2,d.height/2);

dp.gettopPanel().setBackground(new Color(0,0,255,50));
dp.getbottomPanel().setBackground(Color.red);

model = new SpinnerNumberModel(dp.getRotation(), 0, 20, 1);
model.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent ce) {
dp.setRotation((Integer)model.getValue());
}
});

spinner = new JSpinner(model);
jcb = new JCheckBox("コンポーネント範囲外への移動",dp.getOverRotation());
jcb.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent ce) {
dp.setOverRotation(jcb.isSelected());
}
});
GBLayout.addGB(spinner, dp.gettopPanel(), 0, 0, 1, 1);
GBLayout.addGB(jcb, dp.getbottomPanel(), 0, 0, 1, 1);

GBLayout.addGB(dp, this, 0, 0, 1, 1);
//GBLayout.addGB(new JLabel("test"), this.getContentPane(), 1, 0, 1, 1);
this.setLocation(300, 300);
this.pack();
//this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setVisible(true);

//this.setFocusable(false);
}
}


二層のスクロールするJPanel

package program;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.JPanel;

public class DraggedPane extends JPanel
implements MouseWheelListener{


private JPanel topPanel, bottomPanel;
private int rotvalue = 10;
private boolean overRotation = false;
private int paneheight;

DraggedPane(Dimension size, int height, int location){
this.setPreferredSize(size);

this.addMouseWheelListener(this);
this.setLayout(null);//レイアウトマネージャーを無効にする。

bottomPanel = new JPanel();
bottomPanel.addMouseWheelListener(this);
topPanel = new JPanel();
topPanel.addMouseWheelListener(this);

bottomPanel.setBounds(0, 0, size.width, size.height);
topPanel.setBounds(0, location, size.width, height);


this.add(topPanel);
this.add(bottomPanel);

this.setFocusable(true);
}

public JPanel getbottomPanel(){
return(bottomPanel);
}

public JPanel gettopPanel(){
return(topPanel);
}

public void setRotation(int value){
rotvalue = value;
}

public int getRotation(){
return(rotvalue);
}

public boolean getOverRotation(){
return(overRotation);
}

public void setOverRotation(boolean tof){
overRotation=tof;
}

public void setPreferredSize(Dimension d){
super.setPreferredSize(d);
paneheight=d.height;
}

public void mouseWheelMoved(MouseWheelEvent mwe) {
Rectangle rect = topPanel.getBounds();
rect.y = rect.y+rotvalue*mwe.getWheelRotation();

if(overRotation){
topPanel.setBounds(rect);
}else{
if(rect.y<0)rect.y=0;
if(rect.y>paneheight)rect.y=paneheight;
topPanel.setBounds(rect);
}


}

}


概要
JPanelをsetLayout(null)でレイアウトをなくし、座標の絶対配置にするようにして、
そこに二つのJPanelをセットしています。二つのうち上にくるtopPanelがマウスホイールで
動くようにしています。
今回はわかりやすいようにJPanelに色を付けました。
またレイアウトをなくしたときに、どちらのJPanelが上に来るかはadd()の順番によって
変わるので注意が必要です。
とりあえずtopPanel、bottomPanelともにレイアウトをセットすることはできます。
DraggedPane自身のレイアウトを変更はしないでください。

課題
JScrolPaneのビューポートのように上にくるtopPanelが範囲外に来た時に隠れるように設定していないのでうまく調節しなくてはいけない。
と思ったら直った。何でだろう。
もうちょっとメソッドなどを調節すれば使う価値のあるクラスじゃないかな。
スポンサーサイト

コメント

コメントの投稿


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

トラックバック

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

FC2Ad

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