root/graph/JavaPopWeb/src/jp/ac/nime/computer/grpsimulator/HistogramViewPanel.java

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. HistogramViewPanel
  2. setHistogram
  3. paint
  4. getParameters
  5. getMinimum
  6. autoBinarySelect
  7. initSelection
  8. finishSelection
  9. select
  10. unselect
  11. addActionListener
  12. removeActionListener
  13. processMouseEvent
  14. 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);
        }

}

/* [<][>][^][v][top][bottom][index][help] */