1 package charactermanaj.ui;
\r
3 import java.awt.BorderLayout;
\r
4 import java.awt.Container;
\r
5 import java.awt.GridBagConstraints;
\r
6 import java.awt.GridBagLayout;
\r
7 import java.awt.GridLayout;
\r
8 import java.awt.Insets;
\r
9 import java.awt.Point;
\r
10 import java.awt.event.ActionEvent;
\r
11 import java.awt.event.ActionListener;
\r
12 import java.awt.event.WindowAdapter;
\r
13 import java.awt.event.WindowEvent;
\r
14 import java.util.Collection;
\r
15 import java.util.HashMap;
\r
16 import java.util.LinkedList;
\r
17 import java.util.Map;
\r
18 import java.util.Properties;
\r
19 import java.util.concurrent.Semaphore;
\r
20 import java.util.concurrent.atomic.AtomicInteger;
\r
21 import java.util.logging.Level;
\r
22 import java.util.logging.Logger;
\r
24 import javax.swing.AbstractAction;
\r
25 import javax.swing.Action;
\r
26 import javax.swing.BorderFactory;
\r
27 import javax.swing.Box;
\r
28 import javax.swing.BoxLayout;
\r
29 import javax.swing.JButton;
\r
30 import javax.swing.JCheckBox;
\r
31 import javax.swing.JComboBox;
\r
32 import javax.swing.JDialog;
\r
33 import javax.swing.JFrame;
\r
34 import javax.swing.JLabel;
\r
35 import javax.swing.JPanel;
\r
36 import javax.swing.JSlider;
\r
37 import javax.swing.JSpinner;
\r
38 import javax.swing.JTabbedPane;
\r
39 import javax.swing.SpinnerNumberModel;
\r
40 import javax.swing.event.ChangeEvent;
\r
41 import javax.swing.event.ChangeListener;
\r
43 import charactermanaj.graphics.filters.ColorConv;
\r
44 import charactermanaj.graphics.filters.ColorConvertParameter;
\r
45 import charactermanaj.model.AppConfig;
\r
46 import charactermanaj.model.ColorGroup;
\r
47 import charactermanaj.model.Layer;
\r
48 import charactermanaj.model.PartsCategory;
\r
49 import charactermanaj.model.PartsIdentifier;
\r
50 import charactermanaj.ui.model.ColorChangeEvent;
\r
51 import charactermanaj.ui.model.ColorChangeListener;
\r
52 import charactermanaj.util.LocalizedResourcePropertyLoader;
\r
57 * カラーダイアログはカテゴリ別に関連づけられており、カテゴリ内の各レイヤーに対応するタブを持つ.<br>
\r
60 public class ColorDialog extends JDialog {
\r
62 private static final long serialVersionUID = 1L;
\r
67 private static final Logger logger = Logger.getLogger(ColorDialog.class.getName());
\r
70 * このカラーダイアログが対応するカテゴリ
\r
72 private final PartsCategory partsCategory;
\r
77 private HashMap<Layer, ColorDialogTabPanel> tabs = new HashMap<Layer, ColorDialogTabPanel>();
\r
82 private JTabbedPane tabbedPane;
\r
85 * レイヤーに対するタブインデックスのマップ
\r
87 private HashMap<Layer, Integer> tabbedPaneIndexMap = new HashMap<Layer, Integer>();
\r
90 * 色変更イベントのリスナのコレクション
\r
92 private LinkedList<ColorChangeListener> listeners = new LinkedList<ColorChangeListener>();
\r
97 private String captionBase;
\r
100 * 現在表示しているカラー情報の対象としているパーツ識別子
\r
102 private PartsIdentifier partsIdentifier;
\r
105 * カテゴリ全体に適用するチェックボックス
\r
107 private JCheckBox chkApplyAll;
\r
111 * @param parent 親フレーム
\r
112 * @param partsCategory カテゴリ
\r
113 * @param colorGroups 選択可能なカラーグループのコレクション
\r
115 public ColorDialog(JFrame parent, PartsCategory partsCategory, Collection<ColorGroup> colorGroups) {
\r
117 this.partsCategory = partsCategory;
\r
119 final Properties strings = LocalizedResourcePropertyLoader.getInstance().getLocalizedProperties("strings/colordialog");
\r
121 String caption = strings.getProperty("colordialog.caption");
\r
122 String name = partsCategory.getLocalizedCategoryName();
\r
123 captionBase = caption + name;
\r
124 setTitle(captionBase);
\r
126 addWindowListener(new WindowAdapter() {
\r
128 public void windowClosing(WindowEvent e) {
\r
133 Container container = getContentPane();
\r
135 this.tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
\r
136 for (final Layer layer : partsCategory.getLayers()) {
\r
138 ColorDialogTabPanel tabContainer = new ColorDialogTabPanel(this, layer, colorGroups);
\r
139 final ColorChangeListener innerListener = new ColorChangeListener() {
\r
140 private Semaphore semaphore = new Semaphore(1); // イベントが循環発生することを防ぐ
\r
141 public void onColorChange(ColorChangeEvent event) {
\r
142 if (semaphore.tryAcquire()) {
\r
144 ColorDialog.this.fireColorChangeEvent(layer, false);
\r
146 semaphore.release();
\r
150 public void onColorGroupChange(ColorChangeEvent event) {
\r
151 if (semaphore.tryAcquire()) {
\r
153 ColorDialog.this.fireColorGroupChangeEvent(layer);
\r
154 ColorDialog.this.fireColorChangeEvent(layer, false);
\r
156 semaphore.release();
\r
161 tabContainer.addColorChangeListener(innerListener);
\r
163 tabbedPane.addTab(layer.getLocalizedName(), tabContainer);
\r
164 tabbedPaneIndexMap.put(layer, tabbedPane.getTabCount() - 1);
\r
165 tabs.put(layer, tabContainer);
\r
168 Action actApply = new AbstractAction(strings.getProperty("button.apply")) {
\r
169 private static final long serialVersionUID = 1L;
\r
170 public void actionPerformed(ActionEvent e) {
\r
174 Action actReset = new AbstractAction(strings.getProperty("button.reset")) {
\r
175 private static final long serialVersionUID = 1L;
\r
176 public void actionPerformed(ActionEvent e) {
\r
177 ColorDialogTabPanel tab = (ColorDialogTabPanel) tabbedPane
\r
178 .getSelectedComponent();
\r
186 JPanel btnPanel = new JPanel();
\r
187 btnPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
\r
188 GridBagLayout gbl = new GridBagLayout();
\r
189 btnPanel.setLayout(gbl);
\r
193 GridBagConstraints gbc = new GridBagConstraints();
\r
194 gbc.gridx = colIdx++;
\r
198 gbc.anchor = GridBagConstraints.EAST;
\r
199 gbc.fill = GridBagConstraints.BOTH;
\r
200 gbc.gridheight = 1;
\r
204 chkApplyAll = new JCheckBox(strings.getProperty("checkbox.applyAllItems"));
\r
205 chkApplyAll.setSelected(!partsCategory.isMultipleSelectable());
\r
206 chkApplyAll.addActionListener(new ActionListener() {
\r
207 public void actionPerformed(ActionEvent e) {
\r
208 // すべてに適用のチェックが変更された場合は全レイヤーの色の変更通知を出す.
\r
212 btnPanel.add(chkApplyAll, gbc);
\r
214 gbc.gridx = colIdx++;
\r
217 btnPanel.add(Box.createHorizontalGlue(), gbc);
\r
219 JButton btnApply = null;
\r
220 AppConfig appConfig = AppConfig.getInstance();
\r
221 if ( !appConfig.isEnableAutoColorChange()) {
\r
222 gbc.gridx = colIdx++;
\r
225 btnApply = new JButton(actApply);
\r
226 btnPanel.add(btnApply, gbc);
\r
229 gbc.gridx = colIdx++;
\r
232 JButton btnReset = new JButton(actReset);
\r
233 btnPanel.add(btnReset, gbc);
\r
235 container.setLayout(new BorderLayout());
\r
236 container.add(tabbedPane, BorderLayout.CENTER);
\r
237 container.add(btnPanel, BorderLayout.SOUTH);
\r
239 if (btnApply != null) {
\r
240 getRootPane().setDefaultButton(btnApply);
\r
247 * ダイアログの表示位置を調整する.<br>
\r
248 * 横位置Xはメインフレームの右側とし、縦位置Yはメインフレームの上位置からのoffset_yを加えた位置とする.<br>
\r
249 * @param offset_y オフセットY
\r
251 public void adjustLocation(int offset_y) {
\r
252 Point pt = getParent().getLocation();
\r
253 Insets insets = getParent().getInsets();
\r
254 pt.x += getParent().getWidth();
\r
255 pt.y += (offset_y * insets.top);
\r
260 * このカラーダイアログが対応するパーツカテゴリを取得する.<br>
\r
263 public PartsCategory getPartsCategory() {
\r
264 return partsCategory;
\r
268 * 指定したレイヤーのカラーグループが「連動」しているか?<br>
\r
269 * カテゴリに属していないレイヤーを指定した場合は常にfalseを返す.<br>
\r
270 * @param layer レイヤー
\r
271 * @return 連動している場合はtrue、そうでなければfalse
\r
273 public boolean isSyncColorGroup(Layer layer) {
\r
274 ColorDialogTabPanel tab = tabs.get(layer);
\r
278 return tab.isSyncColorGroup();
\r
282 * 指定したレイヤーのカラーグループの連動フラグを設定する.<br>
\r
283 * カテゴリに属していないレイヤーを指定した場合は何もしない.<br>
\r
284 * @param layer レイヤー
\r
285 * @param selected 連動フラグ
\r
287 public void setSyncColorGroup(Layer layer, boolean selected) {
\r
288 ColorDialogTabPanel tab = tabs.get(layer);
\r
290 tab.setSyncColorGroup(selected);
\r
295 * レイヤーごとの色情報のマップを指定して、各レイヤーに色情報を設定する.<br>
\r
296 * カテゴリに属していないレイヤーが含まれる場合は例外となる.<br>
\r
297 * @param params レイヤーと色情報のマップ
\r
299 public void setColorConvertParameters(Map<Layer, ColorConvertParameter> params) {
\r
300 if (params == null) {
\r
301 throw new IllegalArgumentException();
\r
303 for (Layer layer : partsCategory.getLayers()) {
\r
304 ColorConvertParameter param = params.get(layer);
\r
305 if (param == null) {
\r
306 param = new ColorConvertParameter();
\r
308 setColorConvertParameter(layer, param);
\r
313 * 対象となるパーツ識別子を指定する。<br>
\r
314 * カラーダイアログのキャプションにパーツ名を設定される.<br>
\r
315 * nullを指定した場合はキャプションからパーツ名が除去される.<br>
\r
316 * @param partsIdentifier パーツ識別子、もしくはnull
\r
318 public void setPartsIdentifier(PartsIdentifier partsIdentifier) {
\r
319 this.partsIdentifier = partsIdentifier;
\r
320 if (partsIdentifier == null) {
\r
321 setTitle(captionBase);
\r
323 setTitle(captionBase + "(" + partsIdentifier.getLocalizedPartsName() + ")");
\r
328 * 対象となるパーツ識別子を取得する.<br>
\r
329 * 設定されていなければnullが返される.<br>
\r
330 * @return パーツ識別子、もしくはnull
\r
332 public PartsIdentifier getPartsIdentifier() {
\r
333 return partsIdentifier;
\r
337 * 各レイヤーのタブの有効・無効状態を設定します.<br>
\r
338 * カテゴリに属さないレイヤーは無視されます.<br>
\r
339 * nullを指定した場合は、すべてのレイヤーが「有効」となります.<br>
\r
340 * @param layers 有効とするレイヤーのコレクション、もしくはnull
\r
342 public void setEnableLayers(Collection<Layer> layers) {
\r
343 for (Map.Entry<Layer, ColorDialogTabPanel> entry : tabs.entrySet()) {
\r
344 Layer layer = entry.getKey();
\r
345 boolean enabled = (layers == null) || layers.contains(layer);
\r
346 Integer tabIndex = tabbedPaneIndexMap.get(layer);
\r
347 if (tabIndex != null) {
\r
348 tabbedPane.setEnabledAt(tabIndex, enabled);
\r
350 if (logger.isLoggable(Level.FINEST)) {
\r
351 logger.log(Level.FINEST, "setEnableLayers(" + layer + ")=" + enabled);
\r
358 * 「すべてに適用」フラグを取得する.<br>
\r
359 * @return すべてに適用フラグ
\r
361 public boolean isApplyAll() {
\r
362 return chkApplyAll.isSelected();
\r
366 * 各レイヤーと、その色情報をマップとして取得する.<br>
\r
367 * @return 各レイヤーと、その色情報のマップ
\r
369 public Map<Layer, ColorConvertParameter> getColorConvertParameters() {
\r
370 HashMap<Layer, ColorConvertParameter> params = new HashMap<Layer, ColorConvertParameter>();
\r
371 for (Layer layer : partsCategory.getLayers()) {
\r
372 ColorDialogTabPanel tab = tabs.get(layer);
\r
373 ColorConvertParameter param = tab.getColorConvertParameter();
\r
374 params.put(layer, param);
\r
380 * レイヤーを指定して、色情報を設定する.<br>
\r
381 * カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
\r
382 * @param layer レイヤー
\r
385 public void setColorConvertParameter(Layer layer, ColorConvertParameter param) {
\r
386 if (layer == null || param == null) {
\r
387 throw new IllegalArgumentException();
\r
389 ColorDialogTabPanel tab = tabs.get(layer);
\r
391 throw new IllegalArgumentException("layer not found. " + layer + "/tabs=" + tabs);
\r
393 tab.setColorConvertParameter(param);
\r
397 * 指定したレイヤーの色情報を取得する.<br>
\r
398 * カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
\r
399 * @param layer レイヤー
\r
402 public ColorConvertParameter getColorConvertParameter(Layer layer) {
\r
403 if (layer == null) {
\r
404 throw new IllegalArgumentException();
\r
406 ColorDialogTabPanel tab = tabs.get(layer);
\r
408 throw new IllegalArgumentException("layer not found. " + layer);
\r
410 return tab.getColorConvertParameter();
\r
414 * 指定したレイヤーのカラーグループを取得する.<br>
\r
415 * カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
\r
416 * @param layer レイヤー
\r
419 public ColorGroup getColorGroup(Layer layer) {
\r
420 if (layer == null) {
\r
421 throw new IllegalArgumentException();
\r
423 ColorDialogTabPanel tab = tabs.get(layer);
\r
425 throw new IllegalArgumentException("layer not found. " + layer);
\r
427 return tab.getColorGroup();
\r
431 * 指定したレイヤーのカラーグループを設定する.<br>
\r
432 * カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
\r
433 * @param layer レイヤー
\r
434 * @param colorGroup カラーグループ
\r
436 public void setColorGroup(Layer layer, ColorGroup colorGroup) {
\r
437 if (layer == null || colorGroup == null) {
\r
438 throw new IllegalArgumentException();
\r
440 ColorDialogTabPanel tab = tabs.get(layer);
\r
442 tab.setColorGroup(colorGroup);
\r
447 * 色ダイアログが変更された場合に通知を受けるリスナーを登録する.<br>
\r
448 * @param listener リスナー
\r
450 public void addColorChangeListener(ColorChangeListener listener) {
\r
451 if (listener == null) {
\r
452 throw new IllegalArgumentException();
\r
454 listeners.add(listener);
\r
458 * 色ダイアログが変更された場合に通知を受けるリスナーを登録解除する.<br>
\r
461 public void removeColorChangeListener(ColorChangeListener listener) {
\r
462 listeners.remove(listener);
\r
466 * 全レイヤーに対するカラー変更イベントを明示的に送信する.
\r
468 protected void apply() {
\r
469 for (Layer layer : getPartsCategory().getLayers()) {
\r
470 ColorDialog.this.fireColorChangeEvent(layer, true);
\r
477 protected void resetColor(ColorDialogTabPanel tab) {
\r
482 * 指定したレイヤーに対するカラー変更イベントを通知する.<br>
\r
483 * ただし、force引数がfalseである場合、アプリケーション設定で即時プレビューが指定されていない場合は通知しない.<br>
\r
484 * @param layer レイヤー
\r
485 * @param force アプリケーション設定に関わらず送信する場合はtrue
\r
487 protected void fireColorChangeEvent(Layer layer, boolean force) {
\r
488 if (layer == null) {
\r
489 throw new IllegalArgumentException();
\r
492 AppConfig appConfig = AppConfig.getInstance();
\r
493 if (!appConfig.isEnableAutoColorChange()) {
\r
497 ColorChangeEvent event = new ColorChangeEvent(this, layer);
\r
498 for (ColorChangeListener listener : listeners) {
\r
499 listener.onColorChange(event);
\r
504 * 色グループが変更されたことを通知する.<br>
\r
505 * @param layer レイヤー
\r
507 protected void fireColorGroupChangeEvent(Layer layer) {
\r
508 if (layer == null) {
\r
509 throw new IllegalArgumentException();
\r
511 ColorChangeEvent event = new ColorChangeEvent(this, layer);
\r
512 for (ColorChangeListener listener : listeners) {
\r
513 listener.onColorGroupChange(event);
\r
518 public String toString() {
\r
519 return "ColorDialog(partsCategory:" + partsCategory + ")";
\r
524 class ColorDialogTabPanel extends JPanel {
\r
525 private static final long serialVersionUID = 1L;
\r
527 private JComboBox cmbColorReplace;
\r
529 private JSpinner spinGray;
\r
531 private JSpinner spinOffsetR;
\r
533 private JSpinner spinOffsetG;
\r
535 private JSpinner spinOffsetB;
\r
537 private JSpinner spinOffsetA;
\r
539 private JSpinner spinFactorR;
\r
541 private JSpinner spinFactorG;
\r
543 private JSpinner spinFactorB;
\r
545 private JSpinner spinFactorA;
\r
547 private JSpinner spinHue;
\r
549 private JSpinner spinSaturation;
\r
551 private JSpinner spinBrightness;
\r
553 private JSpinner spinGammaR;
\r
555 private JSpinner spinGammaG;
\r
557 private JSpinner spinGammaB;
\r
559 private JSpinner spinGammaA;
\r
561 private JComboBox cmbColorGroup;
\r
563 private JCheckBox chkColorGroupSync;
\r
565 private final ColorDialog parent;
\r
568 * パラメータの明示的変更時に他のパラメータへの反映イベントを停止させるためのセマフォ
\r
570 private AtomicInteger changeEventDisableSemaphore = new AtomicInteger();
\r
573 * 明示的に設定されたカラーパラメータを保存する.(リセットに使用するため)
\r
575 private ColorConvertParameter paramOrg = new ColorConvertParameter();
\r
577 private ColorConvertParameter chachedParam;
\r
579 private LinkedList<ColorChangeListener> listeners = new LinkedList<ColorChangeListener>();
\r
581 public void addColorChangeListener(ColorChangeListener listener) {
\r
582 if (listener == null) {
\r
583 throw new IllegalArgumentException();
\r
585 listeners.add(listener);
\r
588 public void removeColorChangeListener(ColorChangeListener listener) {
\r
589 listeners.remove(listener);
\r
592 protected void fireColorChangeEvent(Layer layer) {
\r
593 if (layer == null) {
\r
594 throw new IllegalArgumentException();
\r
596 chachedParam = null;
\r
597 if (changeEventDisableSemaphore.get() <= 0) {
\r
598 ColorChangeEvent event = new ColorChangeEvent(parent, layer);
\r
599 for (ColorChangeListener listener : listeners) {
\r
600 listener.onColorChange(event);
\r
605 protected void fireColorGroupChangeEvent(Layer layer) {
\r
606 if (layer == null) {
\r
607 throw new IllegalArgumentException();
\r
609 chachedParam = null;
\r
610 if (changeEventDisableSemaphore.get() <= 0) {
\r
611 ColorChangeEvent event = new ColorChangeEvent(parent, layer);
\r
612 for (ColorChangeListener listener : listeners) {
\r
613 listener.onColorGroupChange(event);
\r
618 public ColorDialogTabPanel(final ColorDialog parent, final Layer layer, Collection<ColorGroup> colorGroups) {
\r
619 if (parent == null || layer == null || colorGroups == null) {
\r
620 throw new IllegalArgumentException();
\r
622 this.parent = parent;
\r
624 final Properties strings = LocalizedResourcePropertyLoader.getInstance().getLocalizedProperties("strings/colordialog");
\r
626 setLayout(new BorderLayout());
\r
627 JPanel container = new JPanel();
\r
628 BoxLayout boxlayout = new BoxLayout(container, BoxLayout.PAGE_AXIS);
\r
629 container.setLayout(boxlayout);
\r
630 add(container, BorderLayout.NORTH);
\r
633 final ChangeListener changeEventHandler = new ChangeListener() {
\r
634 public void stateChanged(ChangeEvent e) {
\r
635 fireColorChangeEvent(layer);
\r
641 JPanel colorReplacePanel = new JPanel();
\r
642 colorReplacePanel.setBorder(BorderFactory.createCompoundBorder(
\r
643 BorderFactory.createEmptyBorder(3, 3, 3, 3),
\r
644 BorderFactory.createTitledBorder(strings.getProperty("group.replacergb.caption"))));
\r
645 GridBagLayout gbl = new GridBagLayout();
\r
646 colorReplacePanel.setLayout(gbl);
\r
647 GridBagConstraints gbc = new GridBagConstraints();
\r
649 JLabel lblColorReplace = new JLabel(strings.getProperty("replacergb"), JLabel.RIGHT);
\r
650 cmbColorReplace = new JComboBox(ColorConv.values());
\r
651 JLabel lblGray = new JLabel(strings.getProperty("bright"), JLabel.RIGHT);
\r
652 SpinnerNumberModel grayModel = new SpinnerNumberModel(1., 0., 1., 0.05);
\r
653 grayModel.addChangeListener(changeEventHandler);
\r
654 cmbColorReplace.addActionListener(new ActionListener() {
\r
655 public void actionPerformed(ActionEvent e) {
\r
656 fireColorChangeEvent(layer);
\r
659 spinGray = new JSpinner(grayModel);
\r
664 gbc.gridheight = 1;
\r
667 gbc.anchor = GridBagConstraints.WEST;
\r
668 gbc.fill = GridBagConstraints.BOTH;
\r
671 gbc.insets = new Insets(3, 3, 3, 3);
\r
672 colorReplacePanel.add(lblColorReplace, gbc);
\r
677 gbc.gridheight = 1;
\r
680 colorReplacePanel.add(cmbColorReplace, gbc);
\r
685 gbc.gridheight = 1;
\r
688 colorReplacePanel.add(lblGray, gbc);
\r
695 gbc.gridheight = 1;
\r
696 colorReplacePanel.add(spinGray, gbc);
\r
700 JPanel colorLevelPanel = new JPanel();
\r
701 colorLevelPanel.setBorder(BorderFactory.createCompoundBorder(
\r
702 BorderFactory.createEmptyBorder(3, 3, 3, 3),
\r
703 BorderFactory.createTitledBorder(strings.getProperty("group.rgb.caption"))));
\r
704 GridLayout gl = new GridLayout(4, 5);
\r
707 colorLevelPanel.setLayout(gl);
\r
708 colorLevelPanel.add(Box.createGlue());
\r
709 colorLevelPanel.add(new JLabel(strings.getProperty("red"), JLabel.CENTER));
\r
710 colorLevelPanel.add(new JLabel(strings.getProperty("green"), JLabel.CENTER));
\r
711 colorLevelPanel.add(new JLabel(strings.getProperty("blue"), JLabel.CENTER));
\r
712 colorLevelPanel.add(new JLabel(strings.getProperty("alpha"), JLabel.CENTER));
\r
713 colorLevelPanel.add(new JLabel(strings.getProperty("offset"), JLabel.RIGHT));
\r
714 SpinnerNumberModel offsetModelR = new SpinnerNumberModel(0, -255, 255, 1);
\r
715 SpinnerNumberModel offsetModelG = new SpinnerNumberModel(0, -255, 255, 1);
\r
716 SpinnerNumberModel offsetModelB = new SpinnerNumberModel(0, -255, 255, 1);
\r
717 SpinnerNumberModel offsetModelA = new SpinnerNumberModel(0, -255, 255, 1);
\r
718 offsetModelR.addChangeListener(changeEventHandler);
\r
719 offsetModelG.addChangeListener(changeEventHandler);
\r
720 offsetModelB.addChangeListener(changeEventHandler);
\r
721 offsetModelA.addChangeListener(changeEventHandler);
\r
722 spinOffsetR = new JSpinner(offsetModelR);
\r
723 spinOffsetG = new JSpinner(offsetModelG);
\r
724 spinOffsetB = new JSpinner(offsetModelB);
\r
725 spinOffsetA = new JSpinner(offsetModelA);
\r
726 colorLevelPanel.add(spinOffsetR);
\r
727 colorLevelPanel.add(spinOffsetG);
\r
728 colorLevelPanel.add(spinOffsetB);
\r
729 colorLevelPanel.add(spinOffsetA);
\r
730 colorLevelPanel.add(new JLabel(strings.getProperty("factor"), JLabel.RIGHT));
\r
731 SpinnerNumberModel factorModelR = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
732 SpinnerNumberModel factorModelG = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
733 SpinnerNumberModel factorModelB = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
734 SpinnerNumberModel factorModelA = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
735 factorModelR.addChangeListener(changeEventHandler);
\r
736 factorModelG.addChangeListener(changeEventHandler);
\r
737 factorModelB.addChangeListener(changeEventHandler);
\r
738 factorModelA.addChangeListener(changeEventHandler);
\r
739 spinFactorR = new JSpinner(factorModelR);
\r
740 spinFactorG = new JSpinner(factorModelG);
\r
741 spinFactorB = new JSpinner(factorModelB);
\r
742 spinFactorA = new JSpinner(factorModelA);
\r
743 colorLevelPanel.add(spinFactorR);
\r
744 colorLevelPanel.add(spinFactorG);
\r
745 colorLevelPanel.add(spinFactorB);
\r
746 colorLevelPanel.add(spinFactorA);
\r
747 colorLevelPanel.add(new JLabel(strings.getProperty("gamma"), JLabel.RIGHT));
\r
748 SpinnerNumberModel gammaModelR = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
749 SpinnerNumberModel gammaModelG = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
750 SpinnerNumberModel gammaModelB = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
751 SpinnerNumberModel gammaModelA = new SpinnerNumberModel(1., 0.01, 99, 0.01);
\r
752 gammaModelR.addChangeListener(changeEventHandler);
\r
753 gammaModelG.addChangeListener(changeEventHandler);
\r
754 gammaModelB.addChangeListener(changeEventHandler);
\r
755 gammaModelA.addChangeListener(changeEventHandler);
\r
756 spinGammaR = new JSpinner(gammaModelR);
\r
757 spinGammaG = new JSpinner(gammaModelG);
\r
758 spinGammaB = new JSpinner(gammaModelB);
\r
759 spinGammaA = new JSpinner(gammaModelA);
\r
760 colorLevelPanel.add(spinGammaR);
\r
761 colorLevelPanel.add(spinGammaG);
\r
762 colorLevelPanel.add(spinGammaB);
\r
763 colorLevelPanel.add(spinGammaA);
\r
767 JPanel colorTunePanel = new JPanel();
\r
768 colorTunePanel.setBorder(BorderFactory.createCompoundBorder(
\r
769 BorderFactory.createEmptyBorder(3, 3, 3, 3),
\r
770 BorderFactory.createTitledBorder(strings.getProperty("group.hsb.caption"))));
\r
771 GridLayout gl2 = new GridLayout(3, 3);
\r
774 colorTunePanel.setLayout(gl2);
\r
775 colorTunePanel.add(new JLabel(strings.getProperty("hue"), JLabel.CENTER)); // Hue 色相
\r
776 colorTunePanel.add(new JLabel(strings.getProperty("saturation"), JLabel.CENTER)); // Saturation 彩度
\r
777 colorTunePanel.add(new JLabel(strings.getProperty("brightness"), JLabel.CENTER)); // Brightness 明度
\r
779 SpinnerNumberModel hsbModelH = new SpinnerNumberModel(0., -1., 1., 0.01);
\r
780 SpinnerNumberModel hsbModelS = new SpinnerNumberModel(0., -1., 1., 0.01);
\r
781 SpinnerNumberModel hsbModelB = new SpinnerNumberModel(0., -1., 1., 0.01);
\r
783 hsbModelH.addChangeListener(changeEventHandler);
\r
784 hsbModelS.addChangeListener(changeEventHandler);
\r
785 hsbModelB.addChangeListener(changeEventHandler);
\r
787 spinHue = new JSpinner(hsbModelH);
\r
788 spinSaturation = new JSpinner(hsbModelS);
\r
789 spinBrightness = new JSpinner(hsbModelB);
\r
791 colorTunePanel.add(spinHue);
\r
792 colorTunePanel.add(spinSaturation);
\r
793 colorTunePanel.add(spinBrightness);
\r
795 JSlider sliderHue = new JSlider();
\r
796 JSlider sliderSaturation = new JSlider();
\r
797 JSlider sliderBrightness = new JSlider();
\r
798 sliderHue.setPreferredSize(spinHue.getPreferredSize());
\r
799 sliderSaturation.setPreferredSize(spinSaturation.getPreferredSize());
\r
800 sliderBrightness.setPreferredSize(spinBrightness.getPreferredSize());
\r
801 colorTunePanel.add(sliderHue);
\r
802 colorTunePanel.add(sliderSaturation);
\r
803 colorTunePanel.add(sliderBrightness);
\r
805 JSlider sliders[] = new JSlider[] {sliderHue, sliderSaturation, sliderBrightness};
\r
806 JSpinner spinners[] = new JSpinner[] {spinHue, spinSaturation, spinBrightness};
\r
808 for (int idx = 0; idx < spinners.length; idx++) {
\r
809 final JSlider sl = sliders[idx];
\r
810 final JSpinner sp = spinners[idx];
\r
811 sl.setMinimum(-100);
\r
812 sl.setMaximum(100);
\r
813 sl.setValue((int)(((Number) sp.getValue()).doubleValue() * 100.));
\r
814 final Semaphore loopBlocker = new Semaphore(1); // イベントが循環発生することを防ぐ
\r
815 sl.addChangeListener(new ChangeListener() {
\r
816 public void stateChanged(ChangeEvent e) {
\r
817 if (loopBlocker.tryAcquire()) {
\r
819 double rate = sl.getValue() / 100.;
\r
820 sp.setValue(Double.valueOf(rate));
\r
822 loopBlocker.release();
\r
827 sp.addChangeListener(new ChangeListener() {
\r
828 public void stateChanged(ChangeEvent e) {
\r
829 if (loopBlocker.tryAcquire()) {
\r
831 int rate = (int)(((Number) sp.getValue()).doubleValue() * 100.);
\r
834 loopBlocker.release();
\r
842 ColorGroup colorGroup = layer.getColorGroup();
\r
843 JPanel colorGroupPanel = new JPanel();
\r
844 colorGroupPanel.setBorder(BorderFactory.createCompoundBorder(
\r
845 BorderFactory.createEmptyBorder(3, 3, 3, 3),
\r
846 BorderFactory.createTitledBorder(strings.getProperty("colorgroup"))));
\r
847 GridBagLayout gbl2 = new GridBagLayout();
\r
848 colorGroupPanel.setLayout(gbl2);
\r
849 GridBagConstraints gbc2 = new GridBagConstraints();
\r
851 JLabel lblColorGroup = new JLabel(strings.getProperty("group"), JLabel.RIGHT);
\r
852 cmbColorGroup = new JComboBox(colorGroups.toArray(new ColorGroup[colorGroups.size()]));
\r
853 cmbColorGroup.setSelectedItem(colorGroup);
\r
854 cmbColorGroup.addActionListener(new ActionListener() {
\r
855 public void actionPerformed(ActionEvent e) {
\r
856 ColorGroup selColorGroup = (ColorGroup) cmbColorGroup.getSelectedItem();
\r
857 chkColorGroupSync.setSelected(selColorGroup.isEnabled());
\r
858 fireColorGroupChangeEvent(layer);
\r
861 chkColorGroupSync = new JCheckBox(strings.getProperty("synchronized"));
\r
862 chkColorGroupSync.setSelected(layer.isInitSync());
\r
866 gbc2.gridwidth = 1;
\r
867 gbc2.gridheight = 1;
\r
870 gbc2.anchor = GridBagConstraints.WEST;
\r
871 gbc2.fill = GridBagConstraints.BOTH;
\r
874 gbc2.insets = new Insets(3, 3, 3, 3);
\r
875 colorGroupPanel.add(lblColorGroup, gbc2);
\r
879 gbc2.gridwidth = 1;
\r
880 gbc2.gridheight = 1;
\r
883 colorGroupPanel.add(cmbColorGroup, gbc2);
\r
887 gbc2.gridwidth = GridBagConstraints.REMAINDER;
\r
888 gbc2.gridheight = 1;
\r
891 colorGroupPanel.add(chkColorGroupSync, gbc2);
\r
893 if (colorGroupPanel != null) {
\r
894 container.add(colorGroupPanel);
\r
896 container.add(colorLevelPanel);
\r
897 container.add(colorReplacePanel);
\r
898 container.add(colorTunePanel);
\r
901 public void resetColor() {
\r
902 setColorConvertParameter(paramOrg);
\r
905 public void setColorConvertParameter(ColorConvertParameter param) {
\r
906 if (param == null) {
\r
907 throw new IllegalArgumentException();
\r
909 paramOrg = param.clone();
\r
910 ColorConv colorReplace = param.getColorReplace();
\r
911 if (colorReplace == null) {
\r
912 colorReplace = ColorConv.NONE;
\r
914 changeEventDisableSemaphore.incrementAndGet();
\r
916 cmbColorReplace.setSelectedItem(colorReplace);
\r
917 spinGray.setValue(Double.valueOf(param.getGrayLevel()));
\r
918 spinOffsetR.setValue(Integer.valueOf(param.getOffsetR()));
\r
919 spinOffsetG.setValue(Integer.valueOf(param.getOffsetG()));
\r
920 spinOffsetB.setValue(Integer.valueOf(param.getOffsetB()));
\r
921 spinOffsetA.setValue(Integer.valueOf(param.getOffsetA()));
\r
922 spinFactorR.setValue(Double.valueOf(param.getFactorR()));
\r
923 spinFactorG.setValue(Double.valueOf(param.getFactorG()));
\r
924 spinFactorB.setValue(Double.valueOf(param.getFactorB()));
\r
925 spinFactorA.setValue(Double.valueOf(param.getFactorA()));
\r
926 spinGammaR.setValue(Double.valueOf(param.getGammaR()));
\r
927 spinGammaG.setValue(Double.valueOf(param.getGammaG()));
\r
928 spinGammaB.setValue(Double.valueOf(param.getGammaB()));
\r
929 spinGammaA.setValue(Double.valueOf(param.getGammaA()));
\r
930 spinHue.setValue(Double.valueOf(param.getHue()));
\r
931 spinSaturation.setValue(Double.valueOf(param.getSaturation()));
\r
932 spinBrightness.setValue(Double.valueOf(param.getBrightness()));
\r
934 changeEventDisableSemaphore.decrementAndGet();
\r
936 chachedParam = param;
\r
939 public ColorConvertParameter getColorConvertParameter() {
\r
940 if (chachedParam != null) {
\r
941 return chachedParam;
\r
943 ColorConvertParameter param = new ColorConvertParameter();
\r
944 param.setColorReplace((ColorConv) cmbColorReplace.getSelectedItem());
\r
945 param.setGrayLevel(((Number) spinGray.getValue()).floatValue());
\r
946 param.setOffsetR(((Number) spinOffsetR.getValue()).intValue());
\r
947 param.setOffsetG(((Number) spinOffsetG.getValue()).intValue());
\r
948 param.setOffsetB(((Number) spinOffsetB.getValue()).intValue());
\r
949 param.setOffsetA(((Number) spinOffsetA.getValue()).intValue());
\r
950 param.setFactorR(((Number) spinFactorR.getValue()).floatValue());
\r
951 param.setFactorG(((Number) spinFactorG.getValue()).floatValue());
\r
952 param.setFactorB(((Number) spinFactorB.getValue()).floatValue());
\r
953 param.setFactorA(((Number) spinFactorA.getValue()).floatValue());
\r
954 param.setGammaR(((Number) spinGammaR.getValue()).floatValue());
\r
955 param.setGammaG(((Number) spinGammaG.getValue()).floatValue());
\r
956 param.setGammaB(((Number) spinGammaB.getValue()).floatValue());
\r
957 param.setGammaA(((Number) spinGammaA.getValue()).floatValue());
\r
958 param.setHue(((Number) spinHue.getValue()).floatValue());
\r
959 param.setSaturation(((Number) spinSaturation.getValue()).floatValue());
\r
960 param.setBrightness(((Number) spinBrightness.getValue()).floatValue());
\r
961 chachedParam = param;
\r
965 public ColorGroup getColorGroup() {
\r
966 return (ColorGroup) cmbColorGroup.getSelectedItem();
\r
969 public void setColorGroup(ColorGroup colorGroup) {
\r
970 if (colorGroup == null) {
\r
971 colorGroup = ColorGroup.NA;
\r
973 changeEventDisableSemaphore.incrementAndGet();
\r
975 cmbColorGroup.setSelectedItem(colorGroup);
\r
977 changeEventDisableSemaphore.decrementAndGet();
\r
981 public boolean isSyncColorGroup() {
\r
982 return chkColorGroupSync == null ? false : chkColorGroupSync.isSelected();
\r
985 public void setSyncColorGroup(boolean selected) {
\r
986 if (chkColorGroupSync != null) {
\r
987 changeEventDisableSemaphore.incrementAndGet();
\r
989 chkColorGroupSync.setSelected(selected);
\r
991 changeEventDisableSemaphore.decrementAndGet();
\r