/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- HistogramViewPanel
- setHistogram
- paint
- getParameters
- getMinimum
- autoBinarySelect
- initSelection
- finishSelection
- select
- unselect
- addActionListener
- removeActionListener
- processMouseEvent
- processMouseMotionEvent
package jp.ac.nime.computer.grpsimulator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import jp.ac.nime.computer.grpsimulator.ImgPr.*;
/** ヒストグラム画像を表示するためのJComponent継承クラス
* @version 1.0.0
* @author igarashi
*/
public class HistogramViewPanel extends JComponent
{
ActionListener actionListener; // Post action events to listeners
private Color bgColor_;
private Color selectColor_;
private Color unselectColor_;
private int width_;
private int height_;
private int[] histogram_;
private int histMax_;
private int dragBegin_;
private boolean[] selected_;
private boolean pressedLeft_;
private boolean pressedRight_;
public HistogramViewPanel(int width, int height) {
super();
Dimension dim = new Dimension(width,height);
setMaximumSize(dim);
setMinimumSize(dim);
setPreferredSize(dim);
setSize(dim);
width_ = width;
height_ = height;
enableEvents( AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK );
bgColor_ = new Color(255,255,255);
selectColor_ = new Color(0,255,0);
unselectColor_ = new Color(0,128,0);
histogram_ = null;
selected_ = new boolean[100];
initSelection();
// >>> test
//histogram_ = new int[100];
//for (int i=0; i<100; i++) histogram_[i] = 9600;
//histMax_ = 19200;
// <<< test
}
public boolean setHistogram(int[] histogram) {
if (histogram == null || histogram.length < 100) {
return false;
}
/*-----------------+---------------+
|統計の結果の最大値| Y座標の最高値 |
+------------------+---------------+
| 38400以上 | 76800 |
+------------------+---------------+
| 19200<y<=38400 | 38400 |
+------------------+---------------+
| y< 19200 | 19200 |
+------------------+--------------*/
int max = 0;
for (int i = 0; i < 100; i++) {
if (histogram[i] > max) max = histogram[i];
}
if (max > 38400) {
histMax_ = 76800;
} else if (max > 19200) {
histMax_ = 38400;
} else {
histMax_ = 19200;
}
histogram_ = histogram;
repaint();
return true;
}
public void paint(java.awt.Graphics g) {
super.paint(g);
g.setColor(bgColor_);
g.fillRect(0,0,width_,height_);
if (histogram_ != null) {
for (int i = 0; i < 100; i ++) {
int x1 = i * width_ / 100;
int x2 = (i+1) * width_ / 100;
int h = histogram_[i] * height_ / histMax_;
if (h > height_) h = height_;
int w = x2 - x1;
if (w!=0 && h!=0) {
g.setColor( selected_[i] ? selectColor_ : unselectColor_ );
g.fillRect(x1, height_-h, w, h);
}
}
}
}
/** ヒストグラムをintの配列で返す
* @return ヒストグラムを格納したint[100]型の配列(0:非選択,1:選択)
*/
public int[] getParameters() {
if (histogram_ == null) {
return null;
}
int[] param = new int[100];
for (int i = 0; i < 100; i ++) {
param[i] = selected_[i] ? 1 : 0;
}
return param;
}
/** 選択されている領域の最小値を返す
* @return 選択されているヒストグラムの領域の最小値(0〜99)選択されていないときは-1
*/
public int getMinimum() {
int i;
for (i = 0; i < 100; i++) if (selected_[i]) break;
if (i == 100) return -1;
return i;
}
/** 自動的に2値化用にヒストグラムを分割し、中間地点のみを選択する
* (選択イベントも発生する)
*/
public void autoBinarySelect() {
// ヒストグラムを分割して選択、イベント送出
HistogramBinaryAnaDisc hbad = new HistogramBinaryAnaDisc();
int ikiti = hbad.CalcBinary(histogram_, 100);
initSelection();
selected_[ikiti] = true;
finishSelection();
}
/** 選択状態を初期状態に戻す */
public void initSelection() {
for (int i = 0; i < 100; i ++) selected_[i] = false;
}
/** 選択の変更が終了したときに呼び出される */
private void finishSelection() {
if(actionListener != null) {
actionListener.actionPerformed(new ActionEvent(
this, ActionEvent.ACTION_PERFORMED, "ParameterChanged")
);
}
}
/** クリックされた座標からヒストグラムを選択状態にする */
private void select( int x ) {
selected_[ 100 * x / width_ ] = true;
}
/** クリックされた座標からヒストグラムを非選択状態にする */
private void unselect( int x ) {
selected_[ 100 * x / width_ ] = false;
}
/**
* Adds the specified action listener to receive action events
* from this button.
* @param listener the action listener
*/
public void addActionListener(ActionListener listener) {
actionListener = AWTEventMulticaster.add(actionListener, listener);
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
/**
* Removes the specified action listener so it no longer receives
* action events from this button.
* @param listener the action listener
*/
public void removeActionListener(ActionListener listener) {
actionListener = AWTEventMulticaster.remove(actionListener, listener);
}
protected void processMouseEvent( MouseEvent evt ) {
int mod = evt.getModifiers();
switch(evt.getID()) {
case MouseEvent.MOUSE_PRESSED:
if ((mod & MouseEvent.META_MASK) == 0) {
// 左クリック
if (pressedRight_) pressedRight_ = false;
else {
pressedLeft_ = true;
dragBegin_ = evt.getX();
select( dragBegin_ );
repaint();
}
} else {
// 右クリック
if (pressedLeft_) pressedLeft_ = false;
else {
pressedRight_ = true;
dragBegin_ = evt.getX();
unselect( dragBegin_ );
repaint();
}
}
break;
case MouseEvent.MOUSE_RELEASED:
pressedLeft_ = false;
pressedRight_ = false;
finishSelection();
break;
}
super.processMouseEvent(evt);
}
protected void processMouseMotionEvent( MouseEvent evt ) {
if (evt.getID() == MouseEvent.MOUSE_DRAGGED) {
if ( contains(evt.getX(), evt.getY()) && (pressedLeft_||pressedRight_) ) {
int start = dragBegin_;
int end = evt.getX();
if (end < start) {
start = end;
end = dragBegin_;
};
for (int i = start; i <= end; i++) {
if (pressedLeft_) select( i );
else unselect( i );
}
repaint();
}
}
super.processMouseMotionEvent(evt);
}
}