// ============================================================= // RGB カラーのためのデモアプレット // ============================================================= // ・このアプレットではユーザが入力した RGB カラーの値を実際に表 // 示します。入力できる値は一つの基本色あたり 0〜 255 までとな // ります。 // ・このアプレットでは JDK 1.0 のイベントモデルを使用しています。 // import java.applet.*; import java.awt.*; public class RGBColor extends Applet{ private ColorControler control; // 基本色入力用パネル private Choice number; // レベル数値表示形式 private Choice colorModel; // カラーモデル private int radix = 10; // 表示進数 private RGBColorPanel panel; // カラーサンプル表示パネル // =============================================== // アプレットの初期化 // =============================================== // ・AWT コンポーネントの構築と配置を行います。 public void init(){ // 表示色コントロールのための GUI を制作 control = new ColorControler(this); // 表示するカラーモデル用コンポーネント colorModel = new Choice(); colorModel.addItem("RGB Color"); colorModel.addItem("CMY Color"); colorModel.addItem("HBS Color"); // 表示する進数の選択用 GUI コンポーネント number = new Choice(); number.addItem("10進数"); number.addItem("16進数"); // 上の2つを横に並べるためのパネル Panel p = new Panel(); p.setLayout(new GridLayout(1, 2)); p.add(colorModel); p.add(number); // デモンストレーションカラー表示コンポーネント panel = new RGBColorPanel(); // すべてのコンポーネントを配置する this.setLayout(new BorderLayout()); this.add("North", p); this.add("Center", control); this.add("South", panel); return; } // =============================================== // イベントの取得 // =============================================== // ・テキストフィールドのフォーカスの移動で RGB カ // ラーコンポーネントを再描写します。 public boolean handleEvent(Event e){ if(e.id != Event.ACTION_EVENT){ return super.handleEvent(e); } // 表示する進数の変更の場合 if(e.target == number){ if(number.getSelectedIndex() == 0){ if(radix == 10) return true; radix = 10; } else { if(radix == 16) return true; radix = 16; } control.setRadix(radix); return true; // カラーモデル変更の場合 } else if(e.target == colorModel){ switch(colorModel.getSelectedIndex()){ case 1: control.setColorModel(ColorControler.CMY); break; case 2: control.setColorModel(ColorControler.HSB); break; case 0: default: control.setColorModel(ColorControler.RGB); break; } return true; } return super.handleEvent(e); } // ---------------------------------------------- // RGB カラーパネルの更新 // ---------------------------------------------- // ・現在のパラメータから RGB パネルを更新して再 // 描写します。 public void updatePanel(){ // デモンストレーション用コンポーネントの更新 panel.setRGBColor(control.getColor()); return; } } // ======================================================== // ColorControler: カラーコントローラ // ======================================================== // ・このクラスでは3次元による基本色をコントロールを GUI で // 行うためのコンポーネントです。getColor() で現在選択さ // れている色を取得することができます。 // ・このコンポーネントは RGB, CMY, HSB カラーモデルに対応し // ています。カラーモデルの変更は setColorModel() メソッド // によって行われます。 // class ColorControler extends Panel{ private RGBColor color = null; // 色変更を通知するオブジェクト // AWT コンポーネント private Label[] label; // レベルに対するラベル private TextField[] level; // レベルの数値 private Scrollbar[] slider; // レベル用スライダ private int radix = 10; // 表示進数 private int colorModel = 0; // カラーモデル // クラスメンバ public static final int RED = 0; public static final int GREEN = 1; public static final int BLUE = 2; public static final int RGB = 0; public static final int CMY = 1; public static final int HSB = 2; // ラベル文字列 private static final String[][] name = { {"Red", "Green", "Blue"}, {"Cyan", "Magenta", "Yellow"}, {"Hue", "Saturation", "Brightness"}, }; // ===================================================== // コンストラクタ // ===================================================== // ・コンストラクタでは色の変更を通達するオブジェクト // RGBColor を指定します。ユーザにより色が変更されると // RGBColor.updatePanel() メソッドが呼び出されます。 // ・オブジェクトはデフォルトで RGB カラーモデルの黒色が // 選択されています。 public ColorControler(RGBColor rgb){ color = rgb; // 色変更通知オブジェクトの設定 colorModel = RGB; // カラーモデルの設定 // AWT コンポーネントの構築 label = new Label[3]; level = new TextField[3]; slider = new Scrollbar[3]; // レイアウトの設定 GridBagLayout layout = new GridBagLayout(); this.setLayout(layout); for(int i=RED; i<=BLUE; i++){ level[i] = new TextField("0"); slider[i] = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 255); GridBagConstraints c = new GridBagConstraints(); c.ipadx = c.ipady = 0; c.insets = new Insets(1, 1, 1, 1); c.anchor = GridBagConstraints.CENTER; // ラベル部分 c.gridx = 0; c.gridy = i; c.weightx = 0.0; c.weighty = 1.0; c.fill = GridBagConstraints.NONE; label[i] = new Label(name[RGB][i]); layout.setConstraints(label[i], c); this.add(label[i]); // テキストフィールド部分 c.gridx = 1; c.gridy = i; c.weightx = 0.0; c.weighty = 1.0; c.fill = GridBagConstraints.NONE; layout.setConstraints(level[i], c); this.add(level[i]); // スクロールバー部分 c.gridx = 2; c.gridy = i; c.weightx = 4.0; c.weighty = 1.0; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; layout.setConstraints(slider[i], c); this.add(slider[i]); } return; } // ===================================================== // 進数設定 // ===================================================== // ・このコントローラで使用する数値の進数を設定します。 // 設定できるのは 10 と 16 です。 public void setRadix(int rx){ radix = rx; setColorLevel(getColorLevel(RED), RED); setColorLevel(getColorLevel(GREEN), GREEN); setColorLevel(getColorLevel(BLUE), BLUE); return; } // ===================================================== // 色の取得 // ===================================================== // ・現在のコントローラの状態から Color オブジェクトを生 // 成して返します。 public Color getColor(){ int r = getColorLevel(RED); int g = getColorLevel(GREEN); int b = getColorLevel(BLUE); if(colorModel == CMY){ r = 0xFF - r; g = 0xFF - g; b = 0xFF - b; } else if(colorModel == HSB){ float hu = (float)(r/255.0); float sa = (float)(g/255.0); float br = (float)(b/255.0); return Color.getHSBColor(hu, sa, br); } return new Color(r, g, b); } // ==================================================== // カラーモデルの設定 // ==================================================== // ・オブジェクトのカラーモデルを設定します。表示されて // いる情報は、すべて指定されたカラーモデルに対応する // ように変更されます。 public void setColorModel(int model){ int[] level = new int[3]; // 3次元の色レベル Color color = getColor(); // 現在の色を取得 level[0] = color.getRed(); // 赤 level[1] = color.getGreen(); // 緑 level[2] = color.getBlue(); // 青 // CMY カラーモデルの場合 if(model == CMY){ level[0] = 0xFF - level[0]; // シアンに変換 level[1] = 0xFF - level[1]; // マゼンダに変換 level[2] = 0xFF - level[2]; // イエローに変換 // HSB カラーモデルの場合 } else if(model == HSB){ // HSB カラーのレベルに変換 float[] hsb = Color.RGBtoHSB(level[0], level[1], level[2], null); level[0] = (int)(hsb[0] * 255.0); level[1] = (int)(hsb[1] * 255.0); level[2] = (int)(hsb[2] * 255.0); } // 各レベルのラベル文字列を変更 label[0].setText(name[model][0]); label[1].setText(name[model][1]); label[2].setText(name[model][2]); // 新しくカラーモデルを設定 // ※colorModel の代入はここでなければならない。これは // setColorLevel() で colorModel の値を参照するため。 // さらに getColor() でも colorModel() の値を参照する。 colorModel = model; // 各レベルの値を更新する setColorLevel(level[0], RED); setColorLevel(level[1], GREEN); setColorLevel(level[2], BLUE); return; } // ==================================================== // カラーレベルの取得 // ==================================================== // ・指定された番号のレベルを 256 階調で取得します。 private int getColorLevel(int i){ int pos = slider[i].getValue(); int max = slider[i].getMaximum(); int min = slider[i].getMinimum(); return (int)((255.0 * (pos-min)) / (max-min)); } // ==================================================== // カラーレベルの設定 // ==================================================== // ・指定された番号のレベルを変更します。値が変更される // と RGBColor オブジェクトに通知されます。 private void setColorLevel(int pos, int i){ if(pos > 255) pos = 255; if(pos < 0) pos = 0; int max = slider[i].getMaximum(); int min = slider[i].getMinimum(); String num = Integer.toString(pos, radix); level[i].setText(num.toUpperCase()); slider[i].setValue((max-min)*pos/255); // 色が変更されたことを通知する color.updatePanel(); return; } // =============================================== // イベントの取得 // =============================================== // ・テキストフィールドのフォーカスの移動で RGB カ // ラーコンポーネントを再描写します。 public boolean handleEvent(Event e){ int pos = 0; // スクロールバーのイベント if(e.target instanceof Scrollbar){ if(e.id != Event.SCROLL_LINE_UP && e.id != Event.SCROLL_LINE_DOWN && e.id != Event.SCROLL_PAGE_UP && e.id != Event.SCROLL_PAGE_DOWN && e.id != Event.SCROLL_ABSOLUTE){ return super.handleEvent(e); } for(int i=0; i<3; i++){ if(e.target != slider[i]) continue; pos = ((Integer)e.arg).intValue(); int max = slider[i].getMaximum(); int min = slider[i].getMinimum(); pos = pos * 255 / (max-min); setColorLevel(pos, i); return true; } // テキスト領域のイベント } else if(e.target instanceof TextField){ if(e.id != Event.ACTION_EVENT && e.id != Event.LOST_FOCUS){ return super.handleEvent(e); } for(int i=0; i<3; i++){ if(e.target != level[i]) continue; try{ pos = Integer.parseInt(level[i].getText(), radix); } catch(NumberFormatException nfe){ pos = 0; } setColorLevel(pos, i); return true; } } return super.handleEvent(e); } } // ============================================================ // RGBColorPanel: デモンストレーションカラー表示コンポーネント // ============================================================ // ・このコンポーネントでは指定された色を表示することだけを行い // ます。setRGBColor() によって色が設定されると、コンポーネン // トに表示されている色が更新されます。 class RGBColorPanel extends Canvas{ private Color color; // ========================================== // デフォルトコンストラクタ // ========================================== // ・デフォルトコンストラクタでは黒色を描写し // ます。 public RGBColorPanel(){ color = Color.black; return; } // ========================================== // コンポーネントの描写 // ========================================== // ・現在の設定の状態でコンポーネントを描写し // ます。 public void paint(Graphics sg){ sg.setColor(color); sg.fillRect(1, 1, bounds().width-2, bounds().height-2); sg.setColor(Color.black); sg.drawRect(0, 0, bounds().width-1, bounds().height-1); return; } // ========================================== // 画面更新のオーバーライド // ========================================== // ・デフォルトの画面更新ではいったん全領域を // クリアしますが、このコンポーネントではそ // の必要がないため、画面のちらつきを押さえ // るためと効率を上げるために直接 paint() // を呼び出します。 public void update(Graphics g){ paint(g); return; } // ========================================== // コンポーネントカラーの設定 // ========================================== // ・このコンポーネントが描写すべき色を指定し // ます。 public void setRGBColor(Color c){ color = c; repaint(); return; } // ========================================== // カスタムコンポーネントのためのメソッド // ========================================== // ・Canvas クラスから派生したカスタムコンポー // ネントを制作する場合に必要となるメソッド // です。適当な大きさを返しています。 public Dimension minimumSize(){ return new Dimension(10, 10); } public Dimension preferredSize(){ return new Dimension(32, 32); } }