• R/O
  • HTTP
  • SSH
  • HTTPS

CharacterManaJ: Commit

キャラクターなんとかJの本体


Commit MetaInfo

Revisiona51998d51dd649545b21030ad9964f55932c598c (tree)
Time2018-12-31 00:57:56
Authorseraphy <seraphy@user...>
Commiterseraphy

Log Message

Java8環境における、高解像度スクリーンのスケール対応

Change Summary

Incremental Difference

--- a/src/main/java/charactermanaj/Main.java
+++ b/src/main/java/charactermanaj/Main.java
@@ -30,6 +30,7 @@ import charactermanaj.ui.MainFramePartialForMacOSX;
3030 import charactermanaj.ui.MainFramePartialForMacOSX9;
3131 import charactermanaj.ui.ProfileListManager;
3232 import charactermanaj.ui.SelectCharatersDirDialog;
33+import charactermanaj.ui.util.ScaleSupport;
3334 import charactermanaj.util.AWTExceptionLoggingHandler;
3435 import charactermanaj.util.ApplicationLoggerConfigurator;
3536 import charactermanaj.util.ConfigurationDirUtilities;
@@ -237,6 +238,12 @@ public final class Main implements Runnable {
237238 // デフォルトのフォントサイズ、0以下の場合はシステム標準のまま
238239 int defFontSize = appConfig.getDefaultFontSize();
239240
241+ // フォントサイズを画面のスケールの補正にあわせる
242+ if (defFontSize > 0) {
243+ ScaleSupport scaleSupport = ScaleSupport.getDefault();
244+ defFontSize = (int)(defFontSize * scaleSupport.getManualScaleY());
245+ }
246+
240247 // UIデフォルトのフォント設定で、優先フォント以外のフォントファミリが指定されているものを
241248 // すべて最優先フォントファミリに設定する.
242249 // また、設定されたフォントサイズが0よりも大きければ、そのサイズに設定する.
--- a/src/main/java/charactermanaj/ui/AboutBox.java
+++ b/src/main/java/charactermanaj/ui/AboutBox.java
@@ -36,6 +36,7 @@ import javax.swing.text.Document;
3636 import javax.swing.text.EditorKit;
3737
3838 import charactermanaj.model.AppConfig;
39+import charactermanaj.ui.util.ScaleSupport;
3940 import charactermanaj.util.DesktopUtilities;
4041 import charactermanaj.util.DirectoryConfig;
4142 import charactermanaj.util.ErrorMessageHelper;
@@ -45,7 +46,7 @@ import charactermanaj.util.SystemUtil;
4546
4647 /**
4748 * Aboutボックスを表示する.
48- *
49+ *
4950 * @author seraphy
5051 */
5152 public class AboutBox {
@@ -56,7 +57,7 @@ public class AboutBox {
5657 private static Logger logger = Logger.getLogger(AboutBox.class.getName());
5758
5859 private JFrame parent;
59-
60+
6061 public AboutBox(JFrame parent) {
6162 if (parent == null) {
6263 throw new IllegalArgumentException();
@@ -70,7 +71,16 @@ public class AboutBox {
7071 public void showAboutBox() {
7172
7273 final JTabbedPane tabs = new JTabbedPane();
73- tabs.setPreferredSize(new Dimension(500, 400));
74+
75+ // 解像度スケールで補正する
76+ Dimension dim = new Dimension(500, 400);
77+ if (this.parent != null) {
78+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this.parent);
79+ if (scaleSupport != null) {
80+ dim = scaleSupport.manualScaled(dim);
81+ }
82+ }
83+ tabs.setPreferredSize(dim);
7484
7585 final JPanel aboutPanel = createAboutPanel();
7686 final JSysInfoPanel sysInfoPanel = new JSysInfoPanel() {
@@ -81,7 +91,7 @@ public class AboutBox {
8191 setText(getSysInfoText());
8292 }
8393 };
84-
94+
8595 tabs.addTab("About", aboutPanel);
8696 tabs.addTab("System", sysInfoPanel);
8797
@@ -92,10 +102,10 @@ public class AboutBox {
92102 }
93103 }
94104 });
95-
105+
96106 JOptionPane.showMessageDialog(parent, tabs, "About", JOptionPane.INFORMATION_MESSAGE);
97107 }
98-
108+
99109 protected JPanel createAboutPanel() {
100110 LocalizedTextResource textResource = new LocalizedTextResource() {
101111 @Override
@@ -111,10 +121,10 @@ public class AboutBox {
111121
112122 String versionInfo = appConfig.getImplementationVersion();
113123 String specificationVersionInfo = appConfig.getSpecificationVersion();
114-
124+
115125 message = message.replace("@@IMPLEMENTS-VERSIONINFO@@", versionInfo);
116126 message = message.replace("@@SPECIFICATION-VERSIONINFO@@", specificationVersionInfo);
117-
127+
118128 JPanel aboutPanel = new JPanel(new BorderLayout());
119129 JEditorPane editorPane = new JEditorPane();
120130 editorPane.addHyperlinkListener(new HyperlinkListener() {
@@ -161,29 +171,29 @@ public class AboutBox {
161171 editorPane.setSelectionStart(0);
162172 editorPane.setSelectionEnd(0);
163173 aboutPanel.add(new JScrollPane(editorPane), BorderLayout.CENTER);
164-
174+
165175 return aboutPanel;
166176 }
167-
177+
168178 /**
169179 * システム情報を取得してHTML形式の文字列として返す.<br>
170180 * ランタイム情報、システムプロパティ情報、環境変数情報を取得する.<br>
171- *
181+ *
172182 * @return システム情報のHTML文字列
173183 */
174184 protected String getSysInfoText() {
175185
176186 // ランタイム情報の取得
177-
187+
178188 long freeMem, totalMem, maxMem;
179189 Runtime rt = Runtime.getRuntime();
180190
181191 totalMem = rt.totalMemory() / 1024;
182192 freeMem = rt.freeMemory() / 1024;
183193 maxMem = rt.maxMemory() / 1024;
184-
194+
185195 DecimalFormat decimalFmt = new DecimalFormat("#,###,##0");
186-
196+
187197 StringBuilder buf = new StringBuilder();
188198 buf.append("<html>");
189199 buf.append("<h2>Runtime Information</h2>");
@@ -192,9 +202,9 @@ public class AboutBox {
192202 buf.append("<tr><td>Total Memory:</td><td>" + decimalFmt.format(totalMem) + " KiB</td></tr>");
193203 buf.append("<tr><td>Free Memory:</td><td>" + decimalFmt.format(freeMem) + " KiB</td></tr>");
194204 buf.append("</table>");
195-
205+
196206 // キャラクターデータベースの取得
197-
207+
198208 DirectoryConfig dirConfig = DirectoryConfig.getInstance();
199209 String charactersDir = null;
200210 try {
@@ -202,13 +212,13 @@ public class AboutBox {
202212 } catch (RuntimeException ex) {
203213 charactersDir = "**INVALID**";
204214 }
205-
215+
206216 buf.append("<h2>Character Database</h2>");
207217 buf.append("<table border=\"1\">");
208218 buf.append("<tr><td>Location</td>");
209219 buf.append("<td>" + escape(charactersDir) + "</td></tr>");
210220 buf.append("</table>");
211-
221+
212222 // サポートしているエンコーディングの列挙
213223 buf.append("<h2>Available Charsets</h2>");
214224 Charset defaultCharset = Charset.defaultCharset();
@@ -257,9 +267,9 @@ public class AboutBox {
257267 buf.append("<p><span style=\"color: red;\">This system is not supporting Japanese.</span></p>");
258268 }
259269 buf.append(bufChars.toString());
260-
270+
261271 // システムプロパティの取得
262-
272+
263273 buf.append("<h2>System Properties</h2><table border=\"1\">");
264274 try {
265275 Properties sysprops = System.getProperties();
@@ -279,9 +289,9 @@ public class AboutBox {
279289 } catch (Exception ex) {
280290 buf.append(escape(ex.toString()));
281291 }
282-
292+
283293 // 環境変数の取得
284-
294+
285295 buf.append("<h2>System Environments</h2>");
286296 try {
287297 TreeMap<String, String> envMap = new TreeMap<String, String>(); // 環境変数名のアルファベット順にソート
@@ -302,7 +312,7 @@ public class AboutBox {
302312 buf.append("</html>");
303313 return buf.toString();
304314 }
305-
315+
306316 protected String escape(String value) {
307317 if (value == null) {
308318 return null;
@@ -319,16 +329,16 @@ class JSysInfoPanel extends JPanel {
319329 private static final long serialVersionUID = 1L;
320330
321331 private JEditorPane editorPane;
322-
332+
323333 public JSysInfoPanel() {
324334 super(new BorderLayout());
325-
335+
326336 editorPane = new JEditorPane();
327337 editorPane.setEditable(false);
328338 editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
329339 editorPane.setContentType("text/html");
330340 editorPane.setText("");
331-
341+
332342 JButton btnSave = new JButton(new AbstractAction("save") {
333343 private static final long serialVersionUID = 1L;
334344 public void actionPerformed(ActionEvent e) {
@@ -347,21 +357,21 @@ class JSysInfoPanel extends JPanel {
347357 btnPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
348358 btnPanel.add(btnSave, BorderLayout.EAST);
349359 btnPanel.add(btnGc, BorderLayout.WEST);
350-
360+
351361 add(new JScrollPane(editorPane), BorderLayout.CENTER);
352362 add(btnPanel, BorderLayout.SOUTH);
353363 }
354-
364+
355365 public void setText(String message) {
356366 editorPane.setText(message);
357367 editorPane.setSelectionStart(0);
358368 editorPane.setSelectionEnd(0);
359369 }
360-
370+
361371 protected void onGc() {
362372 SystemUtil.gc();
363373 }
364-
374+
365375 protected void onSave() {
366376 JFileChooser chooser = new JFileChooser();
367377 chooser.setSelectedFile(new File("sysinfo.html"));
@@ -384,10 +394,10 @@ class JSysInfoPanel extends JPanel {
384394 } finally {
385395 os.close();
386396 }
387-
397+
388398 } catch (Exception ex) {
389399 ErrorMessageHelper.showErrorDialog(this, ex);
390400 }
391401 }
392-
402+
393403 }
--- a/src/main/java/charactermanaj/ui/AppConfigDialog.java
+++ b/src/main/java/charactermanaj/ui/AppConfigDialog.java
@@ -62,6 +62,7 @@ import javax.swing.table.TableColumnModel;
6262
6363 import charactermanaj.Main;
6464 import charactermanaj.model.AppConfig;
65+import charactermanaj.ui.util.ScaleSupport;
6566 import charactermanaj.util.BeanPropertiesUtilities;
6667 import charactermanaj.util.BeanPropertiesUtilities.PropertyAccessor;
6768 import charactermanaj.util.BeanPropertiesUtilities.PropertyAccessorMap;
@@ -317,14 +318,14 @@ public class AppConfigDialog extends JDialog {
317318 fireTableRowsUpdated(rowIndex, rowIndex);
318319 }
319320
320- public void adjustColumnModel(TableColumnModel columnModel) {
321+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
321322 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
322323 .getLocalizedProperties("languages/appconfigdialog");
323324 int mx = columnModel.getColumnCount();
324325 for (int idx = 0; idx < mx; idx++) {
325326 String reskey = COLUMNS[idx].getResourceKey() + ".width";
326327 int width = Integer.parseInt(strings.getProperty(reskey));
327- columnModel.getColumn(idx).setPreferredWidth(width);
328+ columnModel.getColumn(idx).setPreferredWidth((int)(width * scale));
328329 }
329330 }
330331 }
@@ -454,7 +455,13 @@ public class AppConfigDialog extends JDialog {
454455
455456 add(btnPanel, BorderLayout.SOUTH);
456457
457- setSize(600, 400);
458+ Dimension dim = new Dimension(600, 400);
459+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
460+ if (scaleSupport != null) {
461+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
462+ dim = scaleSupport.manualScaled(dim);
463+ }
464+ setSize(dim);
458465 setLocationRelativeTo(getParent());
459466
460467 // Notes
@@ -574,11 +581,14 @@ public class AppConfigDialog extends JDialog {
574581 appConfigTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
575582 appConfigTable.setCellSelectionEnabled(true);
576583
584+ // 行の高さをフォントの高さにする
585+ appConfigTable.setRowHeight((int)(appConfigTable.getFont().getSize() * 1.2));
586+
577587 // データタイプがColorの場合のセルレンダラーとエディタを設定する
578588 appConfigTable.setDefaultRenderer(Color.class, new ColorCellRender());
579589 appConfigTable.setDefaultEditor(Color.class, new ColorCellEditor());
580590
581- appConfigTableModel.adjustColumnModel(appConfigTable.getColumnModel());
591+ appConfigTableModel.adjustColumnModel(appConfigTable.getColumnModel(), scaleSupport.getManualScaleX());
582592
583593 appConfigTableModel.addTableModelListener(new TableModelListener() {
584594 @Override
--- a/src/main/java/charactermanaj/ui/ExportWizardDialog.java
+++ b/src/main/java/charactermanaj/ui/ExportWizardDialog.java
@@ -88,6 +88,7 @@ import charactermanaj.ui.progress.ProgressHandle;
8888 import charactermanaj.ui.progress.Worker;
8989 import charactermanaj.ui.progress.WorkerException;
9090 import charactermanaj.ui.progress.WorkerWithProgessDialog;
91+import charactermanaj.ui.util.ScaleSupport;
9192 import charactermanaj.util.ErrorMessageHelper;
9293 import charactermanaj.util.LocalizedResourcePropertyLoader;
9394
@@ -296,7 +297,13 @@ public class ExportWizardDialog extends JDialog {
296297
297298 // 表示
298299
299- setSize(500, 500);
300+ Dimension dim = new Dimension(500, 500);
301+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
302+ if (scaleSupport != null) {
303+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
304+ dim = scaleSupport.manualScaled(dim);
305+ }
306+ setSize(dim);
300307 setLocationRelativeTo(parent);
301308
302309 mainPanelLayout.first(mainPanel);
@@ -849,10 +856,12 @@ class ExportPartsSelectPanel extends AbstractImportPanel implements ExportPartsR
849856 partsTable.setGridColor(appConfig.getGridColor());
850857 partsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
851858 partsTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
852- partsTableModel.adjustColumnModel(partsTable.getColumnModel());
853859 partsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
854860 partsTable.setRowSelectionAllowed(true);
855861
862+ // 行の高さをフォントの高さにする
863+ partsTable.setRowHeight((int)(partsTable.getFont().getSize() * 1.2));
864+
856865 Action actPartsSetCheck = new AbstractAction(strings.getProperty("parts.popup.check")) {
857866 private static final long serialVersionUID = 1L;
858867 public void actionPerformed(ActionEvent e) {
@@ -943,6 +952,13 @@ class ExportPartsSelectPanel extends AbstractImportPanel implements ExportPartsR
943952 add(btnPanel, BorderLayout.SOUTH);
944953 }
945954
955+ @Override
956+ public void addNotify() {
957+ super.addNotify();
958+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
959+ partsTableModel.adjustColumnModel(partsTable.getColumnModel(), scaleSupport.getManualScaleX());
960+ }
961+
946962 protected void loadPartsInfo(PartsSpecResolver partsSpecResolver) {
947963 partsTableModel.clear();
948964 for (PartsCategory partsCategory : partsSpecResolver.getPartsCategories()) {
@@ -1104,6 +1120,9 @@ class ExportPresetSelectPanel extends AbstractImportPanel implements ExportPrese
11041120 presetTable.setGridColor(appConfig.getGridColor());
11051121 presetTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
11061122
1123+ // 行の高さをフォントの高さにする
1124+ presetTable.setRowHeight((int)(presetTable.getFont().getSize() * 1.2));
1125+
11071126 final Action actSelectUsedParts = new AbstractAction(
11081127 strings.getProperty("preset.popup.selectUsedParts")) {
11091128 private static final long serialVersionUID = 1L;
@@ -1119,7 +1138,6 @@ class ExportPresetSelectPanel extends AbstractImportPanel implements ExportPrese
11191138
11201139
11211140 presetTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
1122- presetTableModel.adjustColumnModel(presetTable.getColumnModel());
11231141
11241142 add(new JScrollPane(presetTable), BorderLayout.CENTER);
11251143
@@ -1179,6 +1197,13 @@ class ExportPresetSelectPanel extends AbstractImportPanel implements ExportPrese
11791197 add(btnPanel, BorderLayout.SOUTH);
11801198 }
11811199
1200+ @Override
1201+ public void addNotify() {
1202+ super.addNotify();
1203+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
1204+ presetTableModel.adjustColumnModel(presetTable.getColumnModel(), scaleSupport.getManualScaleX());
1205+ }
1206+
11821207 protected void loadPresetInfo(Collection<PartsSet> partsSets, String defaultPresetId) {
11831208 presetTableModel.clear();
11841209 for (PartsSet orgPartsSet : partsSets) {
@@ -1298,9 +1323,9 @@ class ExportPartsTableModel extends AbstractTableModelWithComboBoxModel<ExportPa
12981323 };
12991324 }
13001325
1301- public void adjustColumnModel(TableColumnModel columnModel) {
1326+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
13021327 for (int idx = 0; idx < columnWidths.length; idx++) {
1303- columnModel.getColumn(idx).setPreferredWidth(columnWidths[idx]);
1328+ columnModel.getColumn(idx).setPreferredWidth((int)(columnWidths[idx] * scale));
13041329 }
13051330 }
13061331
@@ -1648,9 +1673,9 @@ class ExportPresetTableModel extends AbstractTableModelWithComboBoxModel<ExportP
16481673
16491674 private String defaultPresetId;
16501675
1651- public void adjustColumnModel(TableColumnModel columnModel) {
1676+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
16521677 for (int idx = 0; idx < columnWidths.length; idx++) {
1653- columnModel.getColumn(idx).setPreferredWidth(columnWidths[idx]);
1678+ columnModel.getColumn(idx).setPreferredWidth((int)(columnWidths[idx] * scale));
16541679 }
16551680 }
16561681
--- a/src/main/java/charactermanaj/ui/ImageSelectPanel.java
+++ b/src/main/java/charactermanaj/ui/ImageSelectPanel.java
@@ -58,6 +58,7 @@ import charactermanaj.model.PartsCategory;
5858 import charactermanaj.model.PartsIdentifier;
5959 import charactermanaj.model.PartsSpec;
6060 import charactermanaj.model.PartsSpecResolver;
61+import charactermanaj.ui.util.ScaleSupport;
6162 import charactermanaj.util.LocalizedResourcePropertyLoader;
6263 import charactermanaj.util.UIHelper;
6364
@@ -221,7 +222,8 @@ public class ImageSelectPanel extends JPanel {
221222 * @param partsCategory パーツカテゴリ
222223 * @param partsSpecResolver キャラクターデータ
223224 */
224- public ImageSelectPanel(final PartsCategory partsCategory, final PartsSpecResolver partsSpecResolver) {
225+ public ImageSelectPanel(ScaleSupport scaleSupport, final PartsCategory partsCategory,
226+ final PartsSpecResolver partsSpecResolver) {
225227 if (partsCategory == null || partsSpecResolver == null) {
226228 throw new IllegalArgumentException();
227229 }
@@ -240,11 +242,13 @@ public class ImageSelectPanel extends JPanel {
240242
241243 partsSelectTableModel = new PartsSelectListModel(partsCategory);
242244
245+ double scale = scaleSupport.getManualScaleX();
246+
243247 final DefaultTableColumnModel columnModel = new DefaultTableColumnModel();
244- TableColumn checkColumn = new TableColumn(0, 32);
245- checkColumn.setMaxWidth(42);
248+ TableColumn checkColumn = new TableColumn(0, (int)(32 * scale));
249+ checkColumn.setMaxWidth((int)(42 * scale));
246250 columnModel.addColumn(checkColumn);
247- columnModel.addColumn(new TableColumn(1, 100));
251+ columnModel.addColumn(new TableColumn(1, (int)(100 * scale)));
248252
249253 final DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
250254 selectionModel.addListSelectionListener(new ListSelectionListener() {
@@ -310,6 +314,7 @@ public class ImageSelectPanel extends JPanel {
310314 return null;
311315 }
312316 };
317+
313318 partsSelectTable.addFocusListener(new FocusAdapter() {
314319 @Override
315320 public void focusGained(FocusEvent e) {
@@ -320,6 +325,10 @@ public class ImageSelectPanel extends JPanel {
320325 partsSelectTable.repaint();
321326 }
322327 });
328+
329+ // 行の高さをフォントの高さにする
330+ partsSelectTable.setRowHeight((int)(partsSelectTable.getFont().getSize() * 1.2));
331+
323332 final JPopupMenu partsSelectTablePopupMenu = new JPopupMenu();
324333 Action actDeselectAll = new AbstractAction(
325334 strings.getProperty("popupmenu.deselectall")) {
@@ -527,6 +536,7 @@ public class ImageSelectPanel extends JPanel {
527536
528537 // デフォルトのパネル幅を設定する.
529538 Dimension dim = new Dimension(200, 200);
539+ dim = scaleSupport.manualScaled(dim);
530540 setPreferredSize(dim);
531541
532542 // パネルの初期サイズ
--- a/src/main/java/charactermanaj/ui/ImportWizardDialog.java
+++ b/src/main/java/charactermanaj/ui/ImportWizardDialog.java
@@ -101,6 +101,7 @@ import charactermanaj.ui.progress.Worker;
101101 import charactermanaj.ui.progress.WorkerException;
102102 import charactermanaj.ui.progress.WorkerWithProgessDialog;
103103 import charactermanaj.ui.util.FileDropTarget;
104+import charactermanaj.ui.util.ScaleSupport;
104105 import charactermanaj.util.ErrorMessageHelper;
105106 import charactermanaj.util.LocalizedResourcePropertyLoader;
106107
@@ -376,7 +377,13 @@ public class ImportWizardDialog extends JDialog {
376377
377378 // 表示
378379
379- setSize(500, 550);
380+ Dimension dim = new Dimension(500, 500);
381+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
382+ if (scaleSupport != null) {
383+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
384+ dim = scaleSupport.manualScaled(dim);
385+ }
386+ setSize(dim);
380387 setLocationRelativeTo(parent);
381388
382389 mainPanelLayout.first(mainPanel);
@@ -1173,9 +1180,9 @@ class URLTableModel extends AbstractTableModelWithComboBoxModel<URLTableRow> {
11731180 }
11741181
11751182
1176- public void adjustColumnModel(TableColumnModel columnModel) {
1183+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
11771184 for (int idx = 0; idx < COLUMN_WIDTHS.length; idx++) {
1178- columnModel.getColumn(idx).setPreferredWidth(COLUMN_WIDTHS[idx]);
1185+ columnModel.getColumn(idx).setPreferredWidth((int)(COLUMN_WIDTHS[idx] * scale));
11791186 }
11801187 }
11811188
@@ -1844,10 +1851,12 @@ class ImportPartsSelectPanel extends ImportWizardCardPanel {
18441851 partsTable.setShowGrid(true);
18451852 partsTable.setGridColor(appConfig.getGridColor());
18461853 partsTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
1847- partsTableModel.adjustColumnModel(partsTable.getColumnModel());
18481854 partsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
18491855 partsTable.setRowSelectionAllowed(true);
18501856
1857+ // 行の高さをフォントの高さにする
1858+ partsTable.setRowHeight((int)(partsTable.getFont().getSize() * 1.2));
1859+
18511860 Action actPartsSetCheck = new AbstractAction(strings.getProperty("parts.popup.check")) {
18521861 private static final long serialVersionUID = 1L;
18531862 public void actionPerformed(ActionEvent e) {
@@ -1949,6 +1958,12 @@ class ImportPartsSelectPanel extends ImportWizardCardPanel {
19491958 add(btnPanel, BorderLayout.SOUTH);
19501959 }
19511960
1961+ @Override
1962+ public void addNotify() {
1963+ super.addNotify();
1964+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
1965+ partsTableModel.adjustColumnModel(partsTable.getColumnModel(), scaleSupport.getDefaultScaleX());
1966+ }
19521967
19531968 @Override
19541969 public void onActive(ImportWizardDialog parent, ImportWizardCardPanel previousPanel) {
@@ -2721,10 +2736,10 @@ class ImportPartsTableModel extends AbstractTableModelWithComboBoxModel<ImportPa
27212736 return false;
27222737 }
27232738
2724- public void adjustColumnModel(TableColumnModel columnModel) {
2739+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
27252740 int mx = columnModel.getColumnCount();
27262741 for (int idx = 0; idx < mx; idx++) {
2727- columnModel.getColumn(idx).setWidth(COLUMN_WIDTHS[idx]);
2742+ columnModel.getColumn(idx).setWidth((int)(COLUMN_WIDTHS[idx] * scale));
27282743 }
27292744 }
27302745
@@ -2918,6 +2933,9 @@ class ImportPresetSelectPanel extends ImportWizardCardPanel {
29182933 presetTable.setGridColor(appConfig.getGridColor());
29192934 presetTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
29202935
2936+ // 行の高さをフォントの高さにする
2937+ presetTable.setRowHeight((int)(presetTable.getFont().getSize() * 1.2));
2938+
29212939 actSelectUsedParts = new AbstractAction(strings.getProperty("preset.popup.selectUsedParts")) {
29222940 private static final long serialVersionUID = 1L;
29232941
@@ -2930,9 +2948,7 @@ class ImportPresetSelectPanel extends ImportWizardCardPanel {
29302948 popupMenu.add(actSelectUsedParts);
29312949
29322950 presetTable.setComponentPopupMenu(popupMenu);
2933-
29342951 presetTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
2935- presetTableModel.adjustColumnModel(presetTable.getColumnModel());
29362952
29372953 add(new JScrollPane(presetTable), BorderLayout.CENTER);
29382954
@@ -2996,6 +3012,13 @@ class ImportPresetSelectPanel extends ImportWizardCardPanel {
29963012 }
29973013
29983014 @Override
3015+ public void addNotify() {
3016+ super.addNotify();
3017+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
3018+ presetTableModel.adjustColumnModel(presetTable.getColumnModel(), scaleSupport.getManualScaleX());
3019+ }
3020+
3021+ @Override
29993022 public void onActive(ImportWizardDialog parent,
30003023 ImportWizardCardPanel previousPanel) {
30013024 this.parent= parent;
@@ -3302,10 +3325,10 @@ class ImportPresetTableModel extends AbstractTableModelWithComboBoxModel<ImportP
33023325 return rowModel.getPartsSet().getPartsSetId().equals(defaultPartsSetId);
33033326 }
33043327
3305- public void adjustColumnModel(TableColumnModel columnModel) {
3328+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
33063329 int mx = columnModel.getColumnCount();
33073330 for (int idx = 0; idx < mx; idx++) {
3308- columnModel.getColumn(idx).setWidth(COLUMN_WIDTHS[idx]);
3331+ columnModel.getColumn(idx).setWidth((int)(COLUMN_WIDTHS[idx] * scale));
33093332 }
33103333 }
33113334
--- a/src/main/java/charactermanaj/ui/InformationDialog.java
+++ b/src/main/java/charactermanaj/ui/InformationDialog.java
@@ -5,6 +5,7 @@ import static java.lang.Math.*;
55 import java.awt.BorderLayout;
66 import java.awt.Component;
77 import java.awt.Container;
8+import java.awt.Dimension;
89 import java.awt.GridBagConstraints;
910 import java.awt.GridBagLayout;
1011 import java.awt.Insets;
@@ -65,6 +66,7 @@ import charactermanaj.model.PartsSpecResolver;
6566 import charactermanaj.model.io.PartsImageCollectionParser;
6667 import charactermanaj.model.io.PartsImageCollectionParser.PartsImageCollectionHandler;
6768 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;
69+import charactermanaj.ui.util.ScaleSupport;
6870 import charactermanaj.util.DesktopUtilities;
6971 import charactermanaj.util.ErrorMessageHelper;
7072 import charactermanaj.util.LocalizedResourcePropertyLoader;
@@ -137,13 +139,17 @@ public class InformationDialog extends JDialog {
137139 return prepareRenderer;
138140 }
139141 };
140- informationTableModel.adjustColumnModel(informationTable.getColumnModel());
142+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
143+ informationTableModel.adjustColumnModel(informationTable.getColumnModel(), scaleSupport.getManualScaleX());
141144 informationTable.setShowGrid(true);
142145 informationTable.setGridColor(appConfig.getGridColor());
143146 informationTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
144147 informationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
145148 informationTable.setRowHeight(informationTable.getRowHeight() + 4);
146149
150+ // 行の高さをフォントの高さにする
151+ informationTable.setRowHeight((int)(informationTable.getFont().getSize() * 1.2));
152+
147153 informationTable.setDefaultRenderer(JButton.class, new ButtonCellRender());
148154 informationTable.setDefaultEditor(JButton.class, new ButtonCellEditor());
149155
@@ -232,7 +238,10 @@ public class InformationDialog extends JDialog {
232238 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeInformationDialog");
233239 am.put("closeInformationDialog", actClose);
234240
235- pack();
241+ // 推奨サイズをスクリーンのスケールで調整する
242+ Dimension dim = getPreferredSize();
243+ dim = scaleSupport.manualScaled(dim);
244+ setSize(dim);
236245 setLocationRelativeTo(parent);
237246 }
238247
@@ -421,9 +430,9 @@ class InformationTableModel extends AbstractTableModelWithComboBoxModel<Informat
421430 }
422431 }
423432
424- public void adjustColumnModel(TableColumnModel columnModel) {
433+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
425434 for (int idx = 0; idx < COLUMNS.length; idx++) {
426- columnModel.getColumn(idx).setPreferredWidth(columnWidths[idx]);
435+ columnModel.getColumn(idx).setPreferredWidth((int)(columnWidths[idx] * scale));
427436 }
428437 }
429438
--- a/src/main/java/charactermanaj/ui/LayerOrderCustomizeDialog.java
+++ b/src/main/java/charactermanaj/ui/LayerOrderCustomizeDialog.java
@@ -72,6 +72,7 @@ import charactermanaj.model.ListChangeListener;
7272 import charactermanaj.model.ObservableList;
7373 import charactermanaj.model.PartsCategory;
7474 import charactermanaj.ui.model.SimpleComboBoxModel;
75+import charactermanaj.ui.util.ScaleSupport;
7576 import charactermanaj.util.LocalizedResourcePropertyLoader;
7677
7778 /**
@@ -390,7 +391,15 @@ public class LayerOrderCustomizeDialog extends JDialog {
390391 tblLayerOrder.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
391392 tblLayerOrder.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
392393
393- dataModel.adjustColumnModel(tblLayerOrder.getColumnModel());
394+ // 行の高さをフォントの高さにする
395+ tblLayerOrder.setRowHeight((int)(tblLayerOrder.getFont().getSize() * 1.2));
396+
397+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
398+ int tableWidth = dataModel.adjustColumnModel(tblLayerOrder.getColumnModel(), scaleSupport.getManualScaleX());
399+
400+ Dimension tablePrefSize = scr.getPreferredSize();
401+ tablePrefSize.width = tableWidth + 10;
402+ scr.setPreferredSize(tablePrefSize);
394403
395404 AbstractAction actAddLayer = new AbstractAction(strings.getProperty("btnAdd")) {
396405 private static final long serialVersionUID = 1L;
@@ -679,11 +688,14 @@ public class LayerOrderCustomizeDialog extends JDialog {
679688 * カラム幅を設定する。
680689 * @param columnModel
681690 */
682- public void adjustColumnModel(TableColumnModel columnModel) {
691+ public int adjustColumnModel(TableColumnModel columnModel, double scale) {
692+ int total = 0;
683693 for (int idx = 0; idx < columns.length; idx++) {
684- columnModel.getColumn(idx).setPreferredWidth(
685- columns[idx].getPrefWidth());
694+ int width = (int)(columns[idx].getPrefWidth() * scale);
695+ columnModel.getColumn(idx).setPreferredWidth(width);
696+ total += width;
686697 }
698+ return total;
687699 }
688700
689701 /**
@@ -1321,8 +1333,9 @@ public class LayerOrderCustomizeDialog extends JDialog {
13211333 am.put("closeAddLayerDialog", actCancel);
13221334
13231335 // コンボボックスの推奨幅を明示的に指定する。(言語によっては幅が小さくなりすぎるため)
1336+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
13241337 Dimension prefSize = cmbCategory.getPreferredSize();
1325- prefSize.width = 200;
1338+ prefSize.width = (int)(200 * scaleSupport.getManualScaleX());
13261339 cmbCategory.setPreferredSize(prefSize);
13271340 pack();
13281341
--- a/src/main/java/charactermanaj/ui/MainFrame.java
+++ b/src/main/java/charactermanaj/ui/MainFrame.java
@@ -119,6 +119,7 @@ import charactermanaj.ui.model.WallpaperFactoryException;
119119 import charactermanaj.ui.model.WallpaperInfo;
120120 import charactermanaj.ui.scrollablemenu.JScrollableMenu;
121121 import charactermanaj.ui.util.FileDropTarget;
122+import charactermanaj.ui.util.ScaleSupport;
122123 import charactermanaj.ui.util.WindowAdjustLocationSupport;
123124 import charactermanaj.util.DesktopUtilities;
124125 import charactermanaj.util.ErrorMessageHelper;
@@ -473,7 +474,14 @@ public class MainFrame extends JFrame
473474 int imageHeight = min(maxHeight, max(400, imageSize != null ? imageSize.height : 0));
474475 // 300x400の画像の場合にメインフレームが600x550だとちょうどいい感じ.
475476 // それ以上大きい画像の場合は増えた分だけフレームを大きくしておく.
476- setSize(imageWidth - 300 + 600, imageHeight - 400 + 550);
477+
478+ Dimension dim = new Dimension(imageWidth - 300 + 600, imageHeight - 400 + 550);
479+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
480+ if (scaleSupport != null) {
481+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
482+ dim = scaleSupport.manualScaled(dim);
483+ }
484+ setSize(dim);
477485
478486 // 現在表示されていなければ、次回表示時にプラットフォーム固有位置に表示するように予約
479487 if (!isShowing()) {
@@ -733,11 +741,13 @@ public class MainFrame extends JFrame
733741
734742 imageSelectPanels = new ImageSelectPanelList();
735743
744+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
745+
736746 JPanel imgSelectPanelsPanel = new JPanel();
737747 BoxLayout bl = new BoxLayout(imgSelectPanelsPanel, BoxLayout.PAGE_AXIS);
738748 imgSelectPanelsPanel.setLayout(bl);
739749 for (PartsCategory category : characterData.getPartsCategories()) {
740- final ImageSelectPanel imageSelectPanel = new ImageSelectPanel(category, characterData);
750+ final ImageSelectPanel imageSelectPanel = new ImageSelectPanel(scaleSupport, category, characterData);
741751 imgSelectPanelsPanel.add(imageSelectPanel);
742752 imageSelectPanels.add(imageSelectPanel);
743753 partsSelectionManager.register(imageSelectPanel);
--- a/src/main/java/charactermanaj/ui/ManageFavoriteDialog.java
+++ b/src/main/java/charactermanaj/ui/ManageFavoriteDialog.java
@@ -48,6 +48,7 @@ import javax.swing.table.AbstractTableModel;
4848
4949 import charactermanaj.model.CharacterData;
5050 import charactermanaj.model.PartsSet;
51+import charactermanaj.ui.util.ScaleSupport;
5152 import charactermanaj.util.LocalizedResourcePropertyLoader;
5253 import charactermanaj.util.UIHelper;
5354
@@ -228,8 +229,10 @@ public class ManageFavoriteDialog extends JDialog {
228229 partsSetListModel = new PartsSetListTableModel();
229230 partsSetList = new JTable(partsSetListModel);
230231 partsSetList.setRowSelectionAllowed(true);
231- partsSetList
232- .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
232+ partsSetList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
233+
234+ // 行の高さをフォントの高さにする
235+ partsSetList.setRowHeight((int)(partsSetList.getFont().getSize() * 1.2));
233236
234237 partsSetList.setTableHeader(null);
235238 partsSetList.getColumnModel().getColumn(1).setMaxWidth(150);
@@ -316,7 +319,13 @@ public class ManageFavoriteDialog extends JDialog {
316319 am.put("deleteFav", actDelete);
317320 am.put("closeManageFavoriteDialog", actCancel);
318321
319- setSize(400, 500);
322+ Dimension dim = new Dimension(400, 500);
323+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
324+ if (scaleSupport != null) {
325+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
326+ dim = scaleSupport.manualScaled(dim);
327+ }
328+ setSize(dim);
320329 setLocationRelativeTo(parent);
321330
322331 final JPopupMenu popupMenu = new JPopupMenu();
--- a/src/main/java/charactermanaj/ui/PartsManageDialog.java
+++ b/src/main/java/charactermanaj/ui/PartsManageDialog.java
@@ -4,6 +4,7 @@ import java.awt.BorderLayout;
44 import java.awt.Color;
55 import java.awt.Component;
66 import java.awt.Container;
7+import java.awt.Dimension;
78 import java.awt.GridBagConstraints;
89 import java.awt.GridBagLayout;
910 import java.awt.Insets;
@@ -68,6 +69,7 @@ import charactermanaj.model.PartsSpec;
6869 import charactermanaj.model.io.PartsInfoXMLReader;
6970 import charactermanaj.model.io.PartsInfoXMLWriter;
7071 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;
72+import charactermanaj.ui.util.ScaleSupport;
7173 import charactermanaj.util.DesktopUtilities;
7274 import charactermanaj.util.ErrorMessageHelper;
7375 import charactermanaj.util.LocalizedResourcePropertyLoader;
@@ -75,33 +77,33 @@ import charactermanaj.util.LocalizedResourcePropertyLoader;
7577 public class PartsManageDialog extends JDialog {
7678
7779 private static final long serialVersionUID = 1L;
78-
80+
7981 protected static final String STRINGS_RESOURCE = "languages/partsmanagedialog";
80-
81-
82+
83+
8284 private static final Logger logger = Logger.getLogger(PartsManageDialog.class.getName());
8385
8486 private CharacterData characterData;
85-
87+
8688 private PartsManageTableModel partsManageTableModel;
87-
89+
8890 private JTable partsManageTable;
89-
91+
9092 private JTextField txtHomepage;
91-
93+
9294 private JTextField txtAuthor;
93-
95+
9496 private boolean updated;
9597
96-
98+
9799 public PartsManageDialog(JFrame parent, CharacterData characterData) {
98100 super(parent, true);
99-
101+
100102 if (characterData == null) {
101103 throw new IllegalArgumentException();
102104 }
103105 this.characterData = characterData;
104-
106+
105107 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
106108 addWindowListener(new WindowAdapter() {
107109 @Override
@@ -116,7 +118,7 @@ public class PartsManageDialog extends JDialog {
116118 setTitle(strings.getProperty("title"));
117119
118120 Container contentPane = getContentPane();
119-
121+
120122 // パーツリストテーブル
121123 JPanel partsListPanel = new JPanel();
122124 partsListPanel.setBorder(BorderFactory.createCompoundBorder(
@@ -125,7 +127,7 @@ public class PartsManageDialog extends JDialog {
125127
126128 GridBagLayout partsListPanelLayout = new GridBagLayout();
127129 partsListPanel.setLayout(partsListPanelLayout);
128-
130+
129131 partsManageTableModel = new PartsManageTableModel();
130132 partsManageTable = new JTable(partsManageTableModel) {
131133 private static final long serialVersionUID = 1L;
@@ -166,12 +168,16 @@ public class PartsManageDialog extends JDialog {
166168 };
167169 partsManageTable.setShowGrid(true);
168170 partsManageTable.setGridColor(AppConfig.getInstance().getGridColor());
169- partsManageTableModel.adjustColumnModel(partsManageTable.getColumnModel());
171+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
172+ partsManageTableModel.adjustColumnModel(partsManageTable.getColumnModel(), scaleSupport.getManualScaleX());
170173 partsManageTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
171174 partsManageTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
172175
176+ // 行の高さをフォントの高さにする
177+ partsManageTable.setRowHeight((int)(partsManageTable.getFont().getSize() * 1.2));
178+
173179 JScrollPane partsManageTableSP = new JScrollPane(partsManageTable);
174-
180+
175181 partsManageTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
176182 public void valueChanged(ListSelectionEvent e) {
177183 if (!e.getValueIsAdjusting()) {
@@ -179,13 +185,13 @@ public class PartsManageDialog extends JDialog {
179185 }
180186 }
181187 });
182-
188+
183189 partsManageTableModel.addTableModelListener(new TableModelListener() {
184190 public void tableChanged(TableModelEvent e) {
185191 onTableDataChange(e.getFirstRow(), e.getLastRow());
186192 }
187193 });
188-
194+
189195 GridBagConstraints gbc = new GridBagConstraints();
190196 gbc.gridx = 0;
191197 gbc.gridy = 0;
@@ -199,7 +205,7 @@ public class PartsManageDialog extends JDialog {
199205 gbc.weightx = 1.;
200206 gbc.weighty = 1.;
201207 partsListPanel.add(partsManageTableSP, gbc);
202-
208+
203209 Action actSortByName = new AbstractAction(strings.getProperty("sortByName")) {
204210 private static final long serialVersionUID = 1L;
205211 public void actionPerformed(ActionEvent e) {
@@ -218,7 +224,7 @@ public class PartsManageDialog extends JDialog {
218224 onSortByTimestamp();
219225 }
220226 };
221-
227+
222228 gbc.gridx = 0;
223229 gbc.gridy = 1;
224230 gbc.gridheight = 1;
@@ -271,9 +277,9 @@ public class PartsManageDialog extends JDialog {
271277 popupMenu.add(new JSeparator());
272278 popupMenu.add(actApplyAllVersion);
273279 popupMenu.add(actApplyAllDownloadURL);
274-
280+
275281 partsManageTable.setComponentPopupMenu(popupMenu);
276-
282+
277283 // 作者情報パネル
278284 JPanel authorPanel = new JPanel();
279285 authorPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
@@ -281,7 +287,7 @@ public class PartsManageDialog extends JDialog {
281287 .createTitledBorder(strings.getProperty("author.info"))));
282288 GridBagLayout authorPanelLayout = new GridBagLayout();
283289 authorPanel.setLayout(authorPanelLayout);
284-
290+
285291 gbc.gridx = 0;
286292 gbc.gridy = 0;
287293 gbc.gridheight = 1;
@@ -330,7 +336,7 @@ public class PartsManageDialog extends JDialog {
330336 if (!DesktopUtilities.isSupported()) {
331337 actBrowseHomepage.setEnabled(false);
332338 }
333-
339+
334340 txtAuthor.getDocument().addDocumentListener(new DocumentListener() {
335341 public void removeUpdate(DocumentEvent e) {
336342 onEditAuthor();
@@ -353,14 +359,14 @@ public class PartsManageDialog extends JDialog {
353359 onEditHomepage();
354360 }
355361 });
356-
357-
362+
363+
358364 // ボタンパネル
359365 JPanel btnPanel = new JPanel();
360366 btnPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 45));
361367 GridBagLayout btnPanelLayout = new GridBagLayout();
362368 btnPanel.setLayout(btnPanelLayout);
363-
369+
364370 Action actClose = new AbstractAction(strings.getProperty("cancel")) {
365371 private static final long serialVersionUID = 1L;
366372 public void actionPerformed(ActionEvent e) {
@@ -373,12 +379,12 @@ public class PartsManageDialog extends JDialog {
373379 onOK();
374380 }
375381 };
376-
382+
377383 gbc.gridx = 0;
378384 gbc.gridy = 0;
379385 gbc.weightx = 1.;
380386 btnPanel.add(Box.createHorizontalGlue(), gbc);
381-
387+
382388 gbc.gridx = Main.isLinuxOrMacOSX() ? 2 : 1;
383389 gbc.gridy = 0;
384390 gbc.weightx = 0.;
@@ -388,16 +394,16 @@ public class PartsManageDialog extends JDialog {
388394 gbc.gridy = 0;
389395 gbc.weightx = 0.;
390396 btnPanel.add(new JButton(actClose), gbc);
391-
397+
392398 // ダイアログ下部
393399 JPanel southPanel = new JPanel(new BorderLayout());
394400 southPanel.add(authorPanel, BorderLayout.NORTH);
395401 southPanel.add(btnPanel, BorderLayout.SOUTH);
396402
397403 contentPane.add(southPanel, BorderLayout.SOUTH);
398-
404+
399405 // キーボード
400-
406+
401407 Toolkit tk = Toolkit.getDefaultToolkit();
402408 JRootPane rootPane = getRootPane();
403409 InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
@@ -408,14 +414,16 @@ public class PartsManageDialog extends JDialog {
408414
409415 // モデル構築
410416 partsManageTableModel.initModel(characterData);
411-
417+
412418 // ウィンドウ配置
413- setSize(500, 400);
419+ Dimension dim = new Dimension(500, 400);
420+ dim = scaleSupport.manualScaled(dim);
421+ setSize(dim);
414422 setLocationRelativeTo(parent);
415423 }
416424
417425 private Semaphore authorEditSemaphore = new Semaphore(1);
418-
426+
419427 protected void onChangeSelection() {
420428 try {
421429 authorEditSemaphore.acquire();
@@ -471,11 +479,11 @@ public class PartsManageDialog extends JDialog {
471479 ErrorMessageHelper.showErrorDialog(this, ex);
472480 }
473481 }
474-
482+
475483 protected void onTableDataChange(int firstRow, int lastRow) {
476484 onChangeSelection();
477485 }
478-
486+
479487 protected void onApplyAllLastModified() {
480488 int[] selRows = partsManageTable.getSelectedRows();
481489 if (selRows.length == 0) {
@@ -520,7 +528,7 @@ public class PartsManageDialog extends JDialog {
520528 return;
521529 }
522530 }
523-
531+
524532 PartsManageTableRow firstRow = partsManageTableModel.getRow(selRows[0]);
525533 String downloadURL = firstRow.getDownloadURL();
526534 if (downloadURL == null) {
@@ -531,7 +539,7 @@ public class PartsManageDialog extends JDialog {
531539 // キャンセルされたか、内容に変化ない場合は何もしない
532540 return;
533541 }
534-
542+
535543 for (int selRow : selRows) {
536544 PartsManageTableRow row = partsManageTableModel.getRow(selRow);
537545 row.setDownloadURL(downloadURL_new);
@@ -541,7 +549,7 @@ public class PartsManageDialog extends JDialog {
541549 }
542550 partsManageTableModel.fireTableRowsUpdated(selRows[0], selRows[selRows.length - 1]);
543551 }
544-
552+
545553 protected void onApplyAllVersion() {
546554 Toolkit tk = Toolkit.getDefaultToolkit();
547555 int[] selRows = partsManageTable.getSelectedRows();
@@ -586,7 +594,7 @@ public class PartsManageDialog extends JDialog {
586594 tk.beep();
587595 return;
588596 }
589-
597+
590598 for (int selRow : selRows) {
591599 PartsManageTableRow row = partsManageTableModel.getRow(selRow);
592600 row.setVersion(version_new);
@@ -596,7 +604,7 @@ public class PartsManageDialog extends JDialog {
596604 }
597605 partsManageTableModel.fireTableRowsUpdated(selRows[0], selRows[selRows.length - 1]);
598606 }
599-
607+
600608 protected void onEditHomepage() {
601609 try {
602610 if (!authorEditSemaphore.tryAcquire()) {
@@ -637,24 +645,24 @@ public class PartsManageDialog extends JDialog {
637645 lastRow = Math.min(lastRow, selRow);
638646 }
639647 }
640-
648+
641649 String homepage = partsManageTableModel.getHomepage(author);
642650 if (homepage == null) {
643651 homepage = "";
644652 }
645653 txtHomepage.setText(homepage);
646-
654+
647655 if (firstRow >= 0) {
648656 partsManageTable.repaint();
649657 }
650658 } finally {
651- authorEditSemaphore.release();
659+ authorEditSemaphore.release();
652660 }
653661 } catch (Exception ex) {
654662 ErrorMessageHelper.showErrorDialog(this, ex);
655663 }
656664 }
657-
665+
658666 protected void onClose() {
659667 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
660668 .getLocalizedProperties(STRINGS_RESOURCE);
@@ -667,7 +675,7 @@ public class PartsManageDialog extends JDialog {
667675 updated = false;
668676 dispose();
669677 }
670-
678+
671679 protected void onBrosweHomepage() {
672680 Toolkit tk = Toolkit.getDefaultToolkit();
673681 String homepage = txtHomepage.getText();
@@ -684,26 +692,26 @@ public class PartsManageDialog extends JDialog {
684692 logger.log(Level.INFO, "browse failed. : " + homepage, ex);
685693 }
686694 }
687-
695+
688696 protected void onSortByAuthor() {
689697 partsManageTableModel.sortByAuthor();
690698 }
691-
699+
692700 protected void onSortByName() {
693701 partsManageTableModel.sortByName();
694702 }
695-
703+
696704 protected void onSortByTimestamp() {
697705 partsManageTableModel.sortByTimestamp();
698706 }
699-
707+
700708 protected void onOK() {
701709 if (partsManageTable.isEditing()) {
702710 Toolkit tk = Toolkit.getDefaultToolkit();
703711 tk.beep();
704712 return;
705713 }
706-
714+
707715 int mx = partsManageTableModel.getRowCount();
708716
709717 // 作者ごとのホームページ情報の取得
@@ -725,34 +733,34 @@ public class PartsManageDialog extends JDialog {
725733 }
726734
727735 PartsManageData partsManageData = new PartsManageData();
728-
736+
729737 // パーツごとの作者とバージョン、ダウンロード先の取得
730738 for (int idx = 0; idx < mx; idx++) {
731739 PartsManageTableRow row = partsManageTableModel.getRow(idx);
732-
740+
733741 String author = row.getAuthor();
734742 PartsAuthorInfo partsAuthorInfo = null;
735743 if (author != null && author.trim().length() > 0) {
736744 partsAuthorInfo = authorInfoMap.get(author.trim());
737745 }
738-
746+
739747 double version = row.getVersion();
740748 String downloadURL = row.getDownloadURL();
741749 String localizedName = row.getLocalizedName();
742750 Timestamp lastModified = row.getLastModified();
743-
751+
744752 PartsManageData.PartsVersionInfo versionInfo = new PartsManageData.PartsVersionInfo();
745753 versionInfo.setVersion(version);
746754 versionInfo.setDownloadURL(downloadURL);
747755 versionInfo.setLastModified(lastModified);
748756
749757 PartsIdentifier partsIdentifier = row.getPartsIdentifier();
750-
758+
751759 PartsManageData.PartsKey partsKey = new PartsManageData.PartsKey(partsIdentifier);
752760 partsManageData.putPartsInfo(partsKey, localizedName,
753761 partsAuthorInfo, versionInfo);
754762 }
755-
763+
756764 // パーツ管理情報を書き込む.
757765 PartsInfoXMLWriter xmlWriter = new PartsInfoXMLWriter();
758766 try {
@@ -763,14 +771,14 @@ public class PartsManageDialog extends JDialog {
763771 ErrorMessageHelper.showErrorDialog(this, ex);
764772 return;
765773 }
766-
774+
767775 updated = true;
768776 dispose();
769777 }
770778
771779 /**
772780 * パーツ管理情報が更新されたか?
773- *
781+ *
774782 * @return 更新された場合はtrue、そうでなければfalse
775783 */
776784 public boolean isUpdated() {
@@ -779,21 +787,21 @@ public class PartsManageDialog extends JDialog {
779787 }
780788
781789 class PartsManageTableRow {
782-
790+
783791 private PartsIdentifier partsIdentifier;
784-
792+
785793 private Timestamp timestamp;
786-
794+
787795 private String localizedName;
788-
796+
789797 private String author;
790-
798+
791799 private String homepage;
792-
800+
793801 private String downloadURL;
794-
802+
795803 private double version;
796-
804+
797805 private Timestamp lastModified;
798806
799807 public PartsManageTableRow(PartsIdentifier partsIdentifier,
@@ -805,9 +813,9 @@ class PartsManageTableRow {
805813 this.localizedName = partsIdentifier.getLocalizedPartsName();
806814
807815 this.timestamp = new Timestamp(partsSpec.getPartsFiles().lastModified());
808-
816+
809817 this.lastModified = lastModified;
810-
818+
811819 PartsAuthorInfo autherInfo = partsSpec.getAuthorInfo();
812820 if (autherInfo != null) {
813821 author = autherInfo.getAuthor();
@@ -822,11 +830,11 @@ class PartsManageTableRow {
822830 downloadURL = partsSpec.getDownloadURL();
823831 version = partsSpec.getVersion();
824832 }
825-
833+
826834 public PartsIdentifier getPartsIdentifier() {
827835 return partsIdentifier;
828836 }
829-
837+
830838 public Timestamp getTimestamp() {
831839 return timestamp;
832840 }
@@ -834,46 +842,46 @@ class PartsManageTableRow {
834842 public String getLocalizedName() {
835843 return localizedName;
836844 }
837-
845+
838846 public void setLocalizedName(String localizedName) {
839847 if (localizedName == null || localizedName.trim().length() == 0) {
840848 throw new IllegalArgumentException();
841849 }
842850 this.localizedName = localizedName;
843851 }
844-
852+
845853 public String getAuthor() {
846854 return author;
847855 }
848-
856+
849857 public String getDownloadURL() {
850858 return downloadURL;
851859 }
852-
860+
853861 public double getVersion() {
854862 return version;
855863 }
856-
864+
857865 public void setAuthor(String author) {
858866 this.author = author;
859867 }
860-
868+
861869 public void setDownloadURL(String downloadURL) {
862870 this.downloadURL = downloadURL;
863871 }
864-
872+
865873 public void setVersion(double version) {
866874 this.version = version;
867875 }
868-
876+
869877 public String getHomepage() {
870878 return homepage;
871879 }
872-
880+
873881 public void setHomepage(String homepage) {
874882 this.homepage = homepage;
875883 }
876-
884+
877885 public Timestamp getLastModified() {
878886 return lastModified;
879887 }
@@ -1040,21 +1048,21 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
10401048 }
10411049 }
10421050
1043-
1051+
10441052 public int getColumnCount() {
10451053 return Columns.values().length;
10461054 }
1047-
1055+
10481056 @Override
10491057 public String getColumnName(int column) {
10501058 return Columns.values()[column].getDisplayName();
10511059 }
1052-
1053- public void adjustColumnModel(TableColumnModel columnModel) {
1060+
1061+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
10541062 Columns[] columns = Columns.values();
10551063 for (int idx = 0; idx < columns.length; idx++) {
10561064 columnModel.getColumn(idx).setPreferredWidth(
1057- columns[idx].getWidth());
1065+ (int)(columns[idx].getWidth() * scale));
10581066 }
10591067 }
10601068
@@ -1063,7 +1071,7 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
10631071 Columns column = Columns.values()[columnIndex];
10641072 return column.getValue(row);
10651073 }
1066-
1074+
10671075 @Override
10681076 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
10691077 PartsManageTableRow row = getRow(rowIndex);
@@ -1080,19 +1088,19 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
10801088 // 変更通知
10811089 fireTableRowsUpdated(rowIndex, columnIndex);
10821090 }
1083-
1091+
10841092 @Override
10851093 public Class<?> getColumnClass(int columnIndex) {
10861094 Columns column = Columns.values()[columnIndex];
10871095 return column.getColumnClass();
10881096 }
1089-
1097+
10901098 @Override
10911099 public boolean isCellEditable(int rowIndex, int columnIndex) {
10921100 Columns column = Columns.values()[columnIndex];
10931101 return column.isEditable();
10941102 }
1095-
1103+
10961104 public void initModel(CharacterData characterData) {
10971105 if (characterData == null) {
10981106 throw new IllegalArgumentException();
@@ -1120,7 +1128,7 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
11201128 .getPartsSpecMap(partsCategory).entrySet()) {
11211129 PartsIdentifier partsIdentifier = entry.getKey();
11221130 PartsSpec partsSpec = entry.getValue();
1123-
1131+
11241132 // パーツ管理情報ファイルから、パーツ管理情報を設定した時点の
11251133 // ファイルサイズや更新日時などを読み取る.
11261134 PartsKey partsKey = new PartsKey(partsIdentifier);
@@ -1147,7 +1155,7 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
11471155 * ホームページはAuthorに対して1つであるが、Authorが自由編集可能であるため便宜的にRowに持たせている.<br>
11481156 * 結果として同じAuthorに対して同じ値を設定する必要がある.<br>
11491157 * ホームページはテーブルに表示されないのでリスナーへの通知は行わない.<br>
1150- *
1158+ *
11511159 * @param author
11521160 * 作者、空またはnullは何もしない.
11531161 * @param homepage
@@ -1171,7 +1179,7 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
11711179 /**
11721180 * ホームページを取得する.<br>
11731181 * 該当する作者がないか、作者がnullまたは空の場合は常にnullを返す.<br>
1174- *
1182+ *
11751183 * @param author
11761184 * 作者
11771185 * @return ホームページ、またはnull
@@ -1191,7 +1199,7 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
11911199 }
11921200 return null;
11931201 }
1194-
1202+
11951203 protected static final Comparator<PartsManageTableRow> NAMED_SORTER
11961204 = new Comparator<PartsManageTableRow>() {
11971205 public int compare(PartsManageTableRow o1, PartsManageTableRow o2) {
@@ -1217,12 +1225,12 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
12171225 return ret;
12181226 }
12191227 };
1220-
1228+
12211229 public void sortByName() {
12221230 Collections.sort(elements, NAMED_SORTER);
12231231 fireTableDataChanged();
12241232 }
1225-
1233+
12261234 public void sortByTimestamp() {
12271235 Collections.sort(elements, new Comparator<PartsManageTableRow>() {
12281236 public int compare(PartsManageTableRow o1, PartsManageTableRow o2) {
--- a/src/main/java/charactermanaj/ui/ProfileEditDialog.java
+++ b/src/main/java/charactermanaj/ui/ProfileEditDialog.java
@@ -76,6 +76,7 @@ import charactermanaj.model.io.CharacterDataDefaultProvider;
7676 import charactermanaj.model.io.CharacterDataDefaultProvider.DefaultCharacterDataVersion;
7777 import charactermanaj.model.io.CharacterDataPersistent;
7878 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;
79+import charactermanaj.ui.util.ScaleSupport;
7980 import charactermanaj.util.DesktopUtilities;
8081 import charactermanaj.util.ErrorMessageHelper;
8182 import charactermanaj.util.LocalizedResourcePropertyLoader;
@@ -565,6 +566,10 @@ public class ProfileEditDialog extends JDialog {
565566 colorGroupTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
566567 colorGroupTable.setRowHeight(colorGroupTable.getRowHeight() + 4);
567568 colorGroupTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
569+
570+ // 行の高さをフォントの高さにする
571+ colorGroupTable.setRowHeight((int)(colorGroupTable.getFont().getSize() * 1.2));
572+
568573 colorGroupPanel.add(new JScrollPane(colorGroupTable), BorderLayout.CENTER);
569574
570575 JPanel colorGroupBtnPanel = new JPanel();
@@ -677,9 +682,14 @@ public class ProfileEditDialog extends JDialog {
677682 categoriesTable.setRowHeight(categoriesTable.getRowHeight() + 4);
678683 categoriesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
679684 categoriesTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
685+
686+ // 行の高さをフォントの高さにする
687+ categoriesTable.setRowHeight((int)(categoriesTable.getFont().getSize() * 1.2));
688+
680689 categoriesPanel.add(new JScrollPane(categoriesTable), BorderLayout.CENTER);
681690
682- categoriesTableModel.adjustColumnModel(categoriesTable.getColumnModel());
691+ ScaleSupport scaleSupprt = ScaleSupport.getInstance(this);
692+ categoriesTableModel.adjustColumnModel(categoriesTable.getColumnModel(), scaleSupprt.getManualScaleX());
683693
684694 JPanel categoriesBtnPanel = new JPanel();
685695 GridBagLayout categoryBtnPanelLayout = new GridBagLayout();
@@ -784,7 +794,8 @@ public class ProfileEditDialog extends JDialog {
784794 return comp;
785795 }
786796 };
787- layersTableModel.adjustColumnModel(layersTable.getColumnModel());
797+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
798+ layersTableModel.adjustColumnModel(layersTable.getColumnModel(), scaleSupport.getManualScaleX());
788799
789800 JComboBox colorGroupCombo = new JComboBox(
790801 new FirstItemInjectionComboBoxModelWrapper<ColorGroupsTableRow>(colorGroupsTableModel, ColorGroupsTableRow.NA));
@@ -801,6 +812,10 @@ public class ProfileEditDialog extends JDialog {
801812
802813 layersTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
803814 layersTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
815+
816+ // 行の高さをフォントの高さにする
817+ layersTable.setRowHeight((int)(layersTable.getFont().getSize() * 1.2));
818+
804819 layersPanel.add(new JScrollPane(layersTable), BorderLayout.CENTER);
805820
806821 JPanel layersBtnPanel = new JPanel();
@@ -917,7 +932,7 @@ public class ProfileEditDialog extends JDialog {
917932 return comp;
918933 }
919934 };
920- partssetsTableModel.adjustColumnModel(partssetsTable.getColumnModel());
935+ partssetsTableModel.adjustColumnModel(partssetsTable.getColumnModel(), scaleSupport.getManualScaleX());
921936
922937 partssetsTable.setRowHeight(layersTable.getRowHeight() + 4);
923938
@@ -926,6 +941,10 @@ public class ProfileEditDialog extends JDialog {
926941 partssetsTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
927942 partssetsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
928943 partssetsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
944+
945+ // 行の高さをフォントの高さにする
946+ partssetsTable.setRowHeight((int)(partssetsTable.getFont().getSize() * 1.2));
947+
929948 partssetsPanel.add(new JScrollPane(partssetsTable), BorderLayout.CENTER);
930949
931950 // Recommendations
@@ -950,7 +969,7 @@ public class ProfileEditDialog extends JDialog {
950969 return comp;
951970 }
952971 };
953- recommendationsTableModel.adjustColumnModel(recommendationsTable.getColumnModel());
972+ recommendationsTableModel.adjustColumnModel(recommendationsTable.getColumnModel(), scaleSupport.getManualScaleX());
954973
955974 recommendationsTable.setRowHeight(layersTable.getRowHeight() + 4);
956975
@@ -960,6 +979,9 @@ public class ProfileEditDialog extends JDialog {
960979 recommendationsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
961980 recommendationsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
962981
982+ // 行の高さをフォントの高さにする
983+ recommendationsTable.setRowHeight((int)(recommendationsTable.getFont().getSize() * 1.2));
984+
963985 recommendationsPanel.add(new JScrollPane(recommendationsTable), BorderLayout.CENTER);
964986
965987 JPanel recommendationsBtnPanel = new JPanel();
@@ -1114,7 +1136,9 @@ public class ProfileEditDialog extends JDialog {
11141136
11151137 contentPane.add(tabbedPane, BorderLayout.CENTER);
11161138
1117- setSize(500, 500);
1139+ Dimension dim = new Dimension(500, 500);
1140+ dim = scaleSupport.manualScaled(dim);
1141+ setSize(dim);
11181142 setLocationRelativeTo(parent);
11191143
11201144 updateUIState();
@@ -2157,12 +2181,12 @@ class CategoriesTableModel extends AbstractTableModelWithComboBoxModel<Categorie
21572181 public CategoriesTableModel() {
21582182 }
21592183
2160- public void adjustColumnModel(TableColumnModel columnModel) {
2184+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
21612185 for (int idx = 0; idx < COLUMNS.length; idx++) {
21622186 ColumnDef columnDef = COLUMNS[idx];
21632187 String reskey = columnDef.getResourceKey();
21642188 int width = Integer.parseInt(strings.getProperty(reskey + ".width"));
2165- columnModel.getColumn(idx).setPreferredWidth(width);
2189+ columnModel.getColumn(idx).setPreferredWidth((int)(width * scale));
21662190 }
21672191 }
21682192
@@ -2431,9 +2455,9 @@ class LayersTableModel extends AbstractTableModelWithComboBoxModel<LayersTableRo
24312455 super();
24322456 }
24332457
2434- public void adjustColumnModel(TableColumnModel columnModel) {
2458+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
24352459 for (int idx = 0; idx < layersColumnWidths.length; idx++) {
2436- columnModel.getColumn(idx).setPreferredWidth(layersColumnWidths[idx]);
2460+ columnModel.getColumn(idx).setPreferredWidth((int)(layersColumnWidths[idx] * scale));
24372461 }
24382462 }
24392463
@@ -2749,9 +2773,9 @@ class PartssetsTableModel extends AbstractTableModelWithComboBoxModel<PresetsTab
27492773 return defaultPartsSetId;
27502774 }
27512775
2752- public void adjustColumnModel(TableColumnModel columnModel) {
2776+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
27532777 for (int idx = 0; idx < partssetsColumnWidths.length; idx++) {
2754- columnModel.getColumn(idx).setPreferredWidth(partssetsColumnWidths[idx]);
2778+ columnModel.getColumn(idx).setPreferredWidth((int)(partssetsColumnWidths[idx] * scale));
27552779 }
27562780 }
27572781
@@ -2956,9 +2980,9 @@ class RecommendationTableModel extends AbstractTableModelWithComboBoxModel<Recom
29562980 public RecommendationTableModel() {
29572981 }
29582982
2959- public void adjustColumnModel(TableColumnModel columnModel) {
2983+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
29602984 for (int idx = 0; idx < partssetsColumnWidths.length; idx++) {
2961- columnModel.getColumn(idx).setPreferredWidth(partssetsColumnWidths[idx]);
2985+ columnModel.getColumn(idx).setPreferredWidth((int)(partssetsColumnWidths[idx] * scale));
29622986 }
29632987 }
29642988
--- a/src/main/java/charactermanaj/ui/ProfileSelectorDialog.java
+++ b/src/main/java/charactermanaj/ui/ProfileSelectorDialog.java
@@ -92,6 +92,7 @@ import charactermanaj.model.io.CustomLayerOrderPersist;
9292 import charactermanaj.model.io.PartsImageDirectoryWatchAgent;
9393 import charactermanaj.model.io.PartsImageDirectoryWatchAgentFactory;
9494 import charactermanaj.ui.util.FileDropTarget;
95+import charactermanaj.ui.util.ScaleSupport;
9596 import charactermanaj.ui.util.SingleRootFileSystemView;
9697 import charactermanaj.util.DesktopUtilities;
9798 import charactermanaj.util.ErrorMessageHelper;
@@ -233,7 +234,11 @@ public class ProfileSelectorDialog extends JDialog {
233234 characterList.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
234235 characterList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
235236
236- characterListModel.adjustColumnModel(characterList.getColumnModel());
237+ // 行の高さをフォントの高さにする
238+ characterList.setRowHeight((int)(characterList.getFont().getSize() * 1.2));
239+
240+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
241+ characterListModel.adjustColumnModel(characterList.getColumnModel(), scaleSupport.getManualScaleX());
237242
238243 characterList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
239244 characterList.getSelectionModel().addListSelectionListener(
@@ -556,7 +561,11 @@ public class ProfileSelectorDialog extends JDialog {
556561
557562 int width = Integer.parseInt(strings.getProperty("windowWidth"));
558563 int height = Integer.parseInt(strings.getProperty("windowHeight"));
559- setSize(width, height);
564+
565+ Dimension dim = new Dimension(width, height);
566+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
567+ dim = scaleSupport.manualScaled(dim);
568+ setSize(dim);
560569 setLocationRelativeTo(parent);
561570
562571 characterList.requestFocus();
@@ -1469,11 +1478,11 @@ class ProfileSelectorTableModel extends AbstractTableModel {
14691478 return rows.size();
14701479 }
14711480
1472- public void adjustColumnModel(TableColumnModel columnModel) {
1481+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
14731482 Columns[] columns = Columns.values();
14741483 for (int idx = 0; idx < columns.length; idx++) {
14751484 columnModel.getColumn(idx).setPreferredWidth(
1476- columns[idx].getWidth());
1485+ (int)(columns[idx].getWidth() * scale));
14771486 }
14781487 }
14791488
--- a/src/main/java/charactermanaj/ui/SearchPartsDialog.java
+++ b/src/main/java/charactermanaj/ui/SearchPartsDialog.java
@@ -2,6 +2,7 @@ package charactermanaj.ui;
22
33 import java.awt.BorderLayout;
44 import java.awt.Container;
5+import java.awt.Dimension;
56 import java.awt.GridBagConstraints;
67 import java.awt.GridBagLayout;
78 import java.awt.Insets;
@@ -51,52 +52,53 @@ import charactermanaj.model.PartsSpec;
5152 import charactermanaj.model.PartsSpecResolver;
5253 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;
5354 import charactermanaj.ui.model.PartsSelectionManager;
55+import charactermanaj.ui.util.ScaleSupport;
5456 import charactermanaj.util.LocalizedResourcePropertyLoader;
5557
5658 public class SearchPartsDialog extends JDialog {
5759
5860 private static final long serialVersionUID = 1L;
59-
60-
61+
62+
6163 private static final WeakHashMap<SearchPartsDialog, Object> ALL_DIALOGS
6264 = new WeakHashMap<SearchPartsDialog, Object>();
63-
64-
65+
66+
6567 protected static final String STRINGS_RESOURCE = "languages/searchpartsdialog";
6668
6769 private PartsSpecResolver partsSpecResolver;
68-
70+
6971 private PartsSelectionManager partsSelectionManager;
70-
72+
7173 private JTable searchPartsTable;
72-
73-
74+
75+
7476 private SearchPartsTableModel searchPartsTableModel;
75-
77+
7678 private JTextField txtPartsName;
77-
79+
7880 private JComboBox cmbAuthors;
79-
81+
8082 private JComboBox cmbCategories;
81-
82-
83+
84+
8385 public static SearchPartsDialog[] getDialogs() {
8486 return ALL_DIALOGS.keySet().toArray(new SearchPartsDialog[ALL_DIALOGS.size()]);
8587 }
86-
87-
88+
89+
8890 public SearchPartsDialog(JFrame parent,
8991 PartsSpecResolver partsSpecResolver,
9092 PartsSelectionManager partsSelectionManager) {
9193 super(parent, false);
92-
94+
9395 if (partsSpecResolver == null) {
9496 throw new IllegalArgumentException();
9597 }
9698
9799 this.partsSpecResolver = partsSpecResolver;
98100 this.partsSelectionManager = partsSelectionManager;
99-
101+
100102 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
101103 addWindowListener(new WindowAdapter() {
102104 @Override
@@ -104,28 +106,28 @@ public class SearchPartsDialog extends JDialog {
104106 onClose();
105107 }
106108 });
107-
108-
109+
110+
109111 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
110112 .getLocalizedProperties(STRINGS_RESOURCE);
111113
112114 setTitle(strings.getProperty("title"));
113-
115+
114116 // モデル
115117 searchPartsTableModel = new SearchPartsTableModel();
116-
117-
118+
119+
118120 // 検索条件パネル
119-
121+
120122 JPanel searchCondPanel = new JPanel();
121123 GridBagLayout searchCondPanelLayout = new GridBagLayout();
122124 searchCondPanel.setLayout(searchCondPanelLayout);
123125 GridBagConstraints gbc = new GridBagConstraints();
124-
126+
125127 searchCondPanel.setBorder(BorderFactory.createCompoundBorder(
126128 BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory
127129 .createTitledBorder(strings.getProperty("search.condition"))));
128-
130+
129131 gbc.gridx = 0;
130132 gbc.gridy = 0;
131133 gbc.gridheight = 1;
@@ -138,19 +140,19 @@ public class SearchPartsDialog extends JDialog {
138140 gbc.weightx = 0.;
139141 gbc.weighty = 0.;
140142 searchCondPanel.add(new JLabel(strings.getProperty("partsname"), JLabel.RIGHT), gbc);
141-
143+
142144 gbc.gridx = 1;
143145 gbc.gridy = 0;
144146 gbc.weightx = 1.;
145147 txtPartsName = new JTextField();
146148 searchCondPanel.add(txtPartsName, gbc);
147-
149+
148150 gbc.gridx = 0;
149151 gbc.gridy = 1;
150152 gbc.gridwidth = 1;
151153 gbc.weightx = 0.;
152154 searchCondPanel.add(new JLabel(strings.getProperty("author"), JLabel.RIGHT), gbc);
153-
155+
154156 gbc.gridx = 1;
155157 gbc.gridy = 1;
156158 gbc.gridwidth = 2;
@@ -160,13 +162,13 @@ public class SearchPartsDialog extends JDialog {
160162 authors.addAll(getAuthors(partsSpecResolver));
161163 cmbAuthors = new JComboBox(authors.toArray(new String[authors.size()]));
162164 searchCondPanel.add(cmbAuthors, gbc);
163-
165+
164166 gbc.gridx = 0;
165167 gbc.gridy = 2;
166168 gbc.gridwidth = 1;
167169 gbc.weightx = 0.;
168170 searchCondPanel.add(new JLabel(strings.getProperty("partscategory"), JLabel.RIGHT), gbc);
169-
171+
170172 gbc.gridx = 1;
171173 gbc.gridy = 2;
172174 gbc.gridwidth = 2;
@@ -192,7 +194,7 @@ public class SearchPartsDialog extends JDialog {
192194 }
193195 });
194196 searchCondPanel.add(btnClear, gbc);
195-
197+
196198 // 検索結果
197199 JPanel searchResult = new JPanel(new BorderLayout());
198200 searchResult.setBorder(BorderFactory.createCompoundBorder(
@@ -201,8 +203,13 @@ public class SearchPartsDialog extends JDialog {
201203 searchPartsTable = new JTable(searchPartsTableModel);
202204 searchPartsTable.setShowGrid(true);
203205 searchPartsTable.setGridColor(AppConfig.getInstance().getGridColor());
206+
207+ // 行の高さをフォントの高さにする
208+ searchPartsTable.setRowHeight((int)(searchPartsTable.getFont().getSize() * 1.2));
209+
204210 JScrollPane searchPartsTableSP = new JScrollPane(searchPartsTable);
205- searchPartsTableModel.adjustColumnModel(searchPartsTable.getColumnModel());
211+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
212+ searchPartsTableModel.adjustColumnModel(searchPartsTable.getColumnModel(), scaleSupport.getManualScaleX());
206213 searchResult.add(searchPartsTableSP, BorderLayout.CENTER);
207214 searchPartsTable.addMouseListener(new MouseAdapter() {
208215 @Override
@@ -214,7 +221,7 @@ public class SearchPartsDialog extends JDialog {
214221 }
215222 }
216223 });
217-
224+
218225 // テーブルのキーイベント
219226 ActionMap tblAm = searchPartsTable.getActionMap();
220227 InputMap tblIm = searchPartsTable.getInputMap();
@@ -225,7 +232,7 @@ public class SearchPartsDialog extends JDialog {
225232 onSelect();
226233 }
227234 });
228-
235+
229236 JPanel btnPanel = new JPanel();
230237 btnPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10));
231238 GridBagLayout btnPanelLayout = new GridBagLayout();
@@ -255,10 +262,10 @@ public class SearchPartsDialog extends JDialog {
255262 });
256263 btnPanel.add(btnSelect, gbc);
257264 searchResult.add(btnPanel, BorderLayout.SOUTH);
258-
259-
265+
266+
260267 // 検索条件の入力が変更されたことを検知するリスナの登録
261-
268+
262269 txtPartsName.getDocument().addDocumentListener(new DocumentListener() {
263270 public void removeUpdate(DocumentEvent e) {
264271 onChangeCondition();
@@ -270,7 +277,7 @@ public class SearchPartsDialog extends JDialog {
270277 onChangeCondition();
271278 }
272279 });
273-
280+
274281 ActionListener changeListener = new ActionListener() {
275282 public void actionPerformed(ActionEvent e) {
276283 onChangeCondition();
@@ -278,7 +285,7 @@ public class SearchPartsDialog extends JDialog {
278285 };
279286 cmbAuthors.addActionListener(changeListener);
280287 cmbCategories.addActionListener(changeListener);
281-
288+
282289 // ESCキーとCTRL-Wで閉じる.
283290 Toolkit tk = Toolkit.getDefaultToolkit();
284291 JRootPane rootPane = getRootPane();
@@ -292,7 +299,7 @@ public class SearchPartsDialog extends JDialog {
292299 onClose();
293300 }
294301 });
295-
302+
296303 // ウィンドウがアクティブになったときに検索フィールドにフォーカスをあてる
297304 addWindowFocusListener(new WindowAdapter() {
298305 public void windowGainedFocus(WindowEvent e) {
@@ -305,14 +312,17 @@ public class SearchPartsDialog extends JDialog {
305312 contentPane.setLayout(new BorderLayout());
306313 contentPane.add(searchCondPanel, BorderLayout.NORTH);
307314 contentPane.add(searchResult, BorderLayout.CENTER);
308-
309- setSize(250, 300);
315+
316+ Dimension dim = new Dimension(250, 300);
317+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
318+ dim = scaleSupport.manualScaled(dim);
319+ setSize(dim);
310320 setLocationRelativeTo(parent);
311-
321+
312322 // ダイアログの登録
313323 ALL_DIALOGS.put(this, null);
314324 }
315-
325+
316326 public List<String> getAuthors(PartsSpecResolver partsSpecResolver) {
317327 if (partsSpecResolver == null) {
318328 throw new IllegalArgumentException();
@@ -327,16 +337,16 @@ public class SearchPartsDialog extends JDialog {
327337 }
328338 }
329339 }
330-
331- ArrayList<String> authors = new ArrayList<String>(authorsSet);
340+
341+ ArrayList<String> authors = new ArrayList<String>(authorsSet);
332342 Collections.sort(authors);
333343 return authors;
334344 }
335-
345+
336346 protected void onClose() {
337347 dispose();
338348 }
339-
349+
340350 /**
341351 * 「選択」ボタンまたはテーブルのダブルクリックのハンドラ.<br>
342352 * 選択されている行のパーツ識別子をもとに、パーツにフォーカスをあてる.<br>
@@ -349,20 +359,20 @@ public class SearchPartsDialog extends JDialog {
349359 partsSelectionManager.setSelection(partsIdentifier);
350360 }
351361 }
352-
362+
353363 protected void onChangeCondition() {
354364 String partsNamesRaw = txtPartsName.getText();
355365 partsNamesRaw = partsNamesRaw.replace(" ", " "); // 全角空白を半角に変換
356366 String[] condPartsNames = partsNamesRaw.split("\\s+");
357-
367+
358368 PartsCategory condPartsCategory = (PartsCategory) cmbCategories.getSelectedItem();
359369 String condAuthor = (String) cmbAuthors.getSelectedItem();
360370 if (condAuthor != null && condAuthor.trim().length() == 0) {
361371 condAuthor = null;
362372 }
363-
373+
364374 ArrayList<Map.Entry<PartsIdentifier, PartsSpec>> partsIdentifiers = new ArrayList<Map.Entry<PartsIdentifier, PartsSpec>>();
365-
375+
366376 for (PartsCategory partsCategory : partsSpecResolver.getPartsCategories()) {
367377 if (condPartsCategory != null && !condPartsCategory.equals(partsCategory)) {
368378 continue;
@@ -397,7 +407,7 @@ public class SearchPartsDialog extends JDialog {
397407 });
398408 searchPartsTableModel.initModel(partsIdentifiers);
399409 }
400-
410+
401411 }
402412
403413 class SearchPartsTableModel extends AbstractTableModelWithComboBoxModel<Map.Entry<PartsIdentifier, PartsSpec>> {
@@ -405,13 +415,13 @@ class SearchPartsTableModel extends AbstractTableModelWithComboBoxModel<Map.Entr
405415 private static final long serialVersionUID = 1L;
406416
407417 private static final String[] COLUMN_NAMES;
408-
418+
409419 private static final int[] COLUMN_WIDTHS;
410-
420+
411421 static {
412422 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
413423 .getLocalizedProperties(SearchPartsDialog.STRINGS_RESOURCE);
414-
424+
415425 COLUMN_NAMES = new String[] {
416426 strings.getProperty("column.partsname"),
417427 strings.getProperty("column.category"),
@@ -423,28 +433,28 @@ class SearchPartsTableModel extends AbstractTableModelWithComboBoxModel<Map.Entr
423433 Integer.parseInt(strings.getProperty("column.author.width")),
424434 };
425435 }
426-
427- public void adjustColumnModel(TableColumnModel columnModel) {
436+
437+ public void adjustColumnModel(TableColumnModel columnModel, double scale) {
428438 for (int idx = 0; idx < COLUMN_WIDTHS.length; idx++) {
429- columnModel.getColumn(idx).setPreferredWidth(COLUMN_WIDTHS[idx]);
439+ columnModel.getColumn(idx).setPreferredWidth((int)(COLUMN_WIDTHS[idx] * scale));
430440 }
431441 }
432-
442+
433443 public int getColumnCount() {
434444 return COLUMN_NAMES.length;
435445 }
436-
446+
437447 @Override
438448 public String getColumnName(int column) {
439449 return COLUMN_NAMES[column];
440450 }
441-
451+
442452 public Object getValueAt(int rowIndex, int columnIndex) {
443453 Map.Entry<PartsIdentifier, PartsSpec> row = getRow(rowIndex);
444-
454+
445455 PartsIdentifier partsIdentifier = row.getKey();
446456 PartsSpec partsSpec = row.getValue();
447-
457+
448458 switch (columnIndex) {
449459 case 0:
450460 return partsIdentifier.getLocalizedPartsName();
@@ -455,7 +465,7 @@ class SearchPartsTableModel extends AbstractTableModelWithComboBoxModel<Map.Entr
455465 }
456466 return "";
457467 }
458-
468+
459469 public void initModel(List<Map.Entry<PartsIdentifier, PartsSpec>> partsIdentifiers) {
460470 clear();
461471 if (partsIdentifiers != null) {
@@ -464,6 +474,6 @@ class SearchPartsTableModel extends AbstractTableModelWithComboBoxModel<Map.Entr
464474 }
465475 }
466476 }
467-
477+
468478 }
469479
--- a/src/main/java/charactermanaj/ui/SelectCharatersDirDialog.java
+++ b/src/main/java/charactermanaj/ui/SelectCharatersDirDialog.java
@@ -1,6 +1,5 @@
11 package charactermanaj.ui;
22
3-import java.awt.BorderLayout;
43 import java.awt.Container;
54 import java.awt.Dimension;
65 import java.awt.Font;
@@ -26,6 +25,7 @@ import java.util.logging.Logger;
2625 import javax.swing.AbstractAction;
2726 import javax.swing.BorderFactory;
2827 import javax.swing.Box;
28+import javax.swing.BoxLayout;
2929 import javax.swing.InputMap;
3030 import javax.swing.JButton;
3131 import javax.swing.JCheckBox;
@@ -42,6 +42,7 @@ import javax.swing.KeyStroke;
4242 import charactermanaj.Main;
4343 import charactermanaj.model.io.WorkingSetPersist;
4444 import charactermanaj.ui.util.FileDropTarget;
45+import charactermanaj.ui.util.ScaleSupport;
4546 import charactermanaj.util.ErrorMessageHelper;
4647 import charactermanaj.util.LocalizedResourcePropertyLoader;
4748 import charactermanaj.util.UIHelper;
@@ -144,9 +145,6 @@ public class SelectCharatersDirDialog extends JDialog {
144145 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
145146 .getLocalizedProperties("languages/selectCharatersDirDialog");
146147
147- Container contentPane = getContentPane();
148- contentPane.setLayout(new BorderLayout(3, 3));
149-
150148 AbstractAction actOk = new AbstractAction(strings.getProperty("btn.ok")) {
151149 private static final long serialVersionUID = 1L;
152150 public void actionPerformed(ActionEvent e) {
@@ -213,108 +211,82 @@ public class SelectCharatersDirDialog extends JDialog {
213211 btnCancel.addFocusListener(focusAdapter);
214212 btnBroseForDir.addFocusListener(focusAdapter);
215213
214+ Container contentPane = getContentPane();
215+ contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
216+
217+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
218+
219+ {
220+ JLabel lbl = new JLabel(strings.getProperty("caption"));
221+ lbl.setFont(lbl.getFont().deriveFont(Font.BOLD));
222+ lbl.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
223+ Dimension dim = lbl.getPreferredSize();
224+ dim.width = Integer.parseInt(strings.getProperty("width"));
225+ dim = scaleSupport.manualScaled(dim);
226+ lbl.setPreferredSize(dim);
227+ Box header = Box.createHorizontalBox();
228+ header.add(lbl);
229+ contentPane.add(header);
230+ }
231+ {
232+ JPanel dirPanel = new JPanel(new GridBagLayout());
233+ dirPanel.setBorder(BorderFactory.createEmptyBorder(3, 10, 3, 3));
234+
235+ combDir = new JComboBox();
236+ combDir.setEditable(true);
237+
238+ GridBagConstraints gbc = new GridBagConstraints();
239+ gbc.gridx = 0;
240+ gbc.gridy = 0;
241+ gbc.insets = new Insets(3, 3, 3, 3);
242+ dirPanel.add(new JLabel(strings.getProperty("lbl.dir")), gbc);
243+
244+ gbc.gridx = 1;
245+ gbc.fill = GridBagConstraints.BOTH;
246+ gbc.weightx = 1;
247+ dirPanel.add(combDir, gbc);
248+
249+ gbc.gridx = 2;
250+ gbc.weightx = 0;
251+ dirPanel.add(btnBroseForDir, gbc);
252+
253+ // リサイズ時に開く余白部
254+ gbc.gridx = 0;
255+ gbc.gridy = 1;
256+ gbc.weighty = 1;
257+ dirPanel.add(Box.createGlue(), gbc);
258+ contentPane.add(dirPanel);
259+ }
216260
217- JPanel dirPanel = new JPanel(new BorderLayout(3, 3));
218- dirPanel.setBorder(BorderFactory.createEmptyBorder(3, 10, 3, 3));
219-
220- JLabel lbl = new JLabel(strings.getProperty("caption"), JLabel.CENTER);
221- lbl.setFont(lbl.getFont().deriveFont(Font.BOLD));
222- lbl.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
223- Dimension dim = lbl.getPreferredSize();
224- dim.width = Integer.parseInt(strings.getProperty("width"));
225- lbl.setPreferredSize(dim);
226- dirPanel.add(lbl, BorderLayout.NORTH);
227-
228- combDir = new JComboBox();
229- combDir.setEditable(true);
230-
231- dirPanel.add(combDir, BorderLayout.CENTER);
232-
233- dirPanel.add(new JLabel(strings.getProperty("lbl.dir")), BorderLayout.WEST);
234- dirPanel.add(btnBroseForDir, BorderLayout.EAST);
235-
236- contentPane.add(dirPanel, BorderLayout.NORTH);
237-
238- JPanel btnPanel = new JPanel();
239- GridBagLayout gbl = new GridBagLayout();
240- btnPanel.setLayout(gbl);
241-
242- chkDoNotAsk = new JCheckBox(strings.getProperty("chk.doNotAskAgein"));
243- chkDoNotAsk.setSelected(recentCharactersDir.isDoNotAskAgain());
244-
245- GridBagConstraints gbc = new GridBagConstraints();
246- gbc.gridx = 0;
247- gbc.gridy = 0;
248- gbc.gridwidth = 5;
249- gbc.gridheight = 1;
250- gbc.weightx = 1.;
251- gbc.weighty = 0.;
252- gbc.fill = GridBagConstraints.BOTH;
253- gbc.anchor = GridBagConstraints.WEST;
254- gbc.ipadx = 0;
255- gbc.ipady = 0;
256- gbc.insets = new Insets(3, 3, 3, 3);
257-
258- btnPanel.add(chkDoNotAsk, gbc);
259-
260- gbc.gridx = 0;
261- gbc.gridy = 1;
262- gbc.gridwidth = 1;
263- gbc.gridheight = 1;
264- gbc.weightx = 0.;
265- gbc.weighty = 0.;
266- btnPanel.add(btnRemoveRecent, gbc);
267-
268- gbc.gridx = 1;
269- gbc.gridy = 1;
270- gbc.gridwidth = 1;
271- gbc.gridheight = 1;
272- gbc.weightx = 0.;
273- gbc.weighty = 0.;
274- btnPanel.add(btnRemoveWorkingSets, gbc);
275-
276- gbc.gridx = 2;
277- gbc.gridy = 1;
278- gbc.gridwidth = 1;
279- gbc.gridheight = 1;
280- gbc.weightx = 1.;
281- gbc.weighty = 0.;
282-
283- btnPanel.add(Box.createGlue(), gbc);
284-
285- gbc.gridx = Main.isLinuxOrMacOSX() ? 4 : 3;
286- gbc.gridy = 1;
287- gbc.gridwidth = 1;
288- gbc.gridheight = 1;
289- gbc.weightx = 0.;
290- gbc.weighty = 0.;
291-
292- btnPanel.add(btnOK, gbc);
293-
294-
295- gbc.gridx = Main.isLinuxOrMacOSX() ? 3 : 4;
296- gbc.gridy = 1;
297- gbc.gridwidth = 1;
298- gbc.gridheight = 1;
299- gbc.weightx = 0.;
300- gbc.weighty = 0.;
301- btnPanel.add(btnCancel, gbc);
302-
303- gbc.gridx = 5;
304- gbc.gridy = 1;
305- gbc.gridwidth = 1;
306- gbc.gridheight = 1;
307- gbc.weightx = 0.;
308- gbc.weighty = 0.;
309- gbc.ipadx = 32;
310- gbc.ipady = 0;
311-
312- btnPanel.add(Box.createGlue(), gbc);
261+ {
262+ chkDoNotAsk = new JCheckBox(strings.getProperty("chk.doNotAskAgein"));
263+ chkDoNotAsk.setSelected(recentCharactersDir.isDoNotAskAgain());
313264
314- setTitle(strings.getProperty("title"));
315- setResizable(false);
265+ Box chkPanel = Box.createHorizontalBox();
266+ chkPanel.add(chkDoNotAsk);
267+ chkPanel.add(Box.createHorizontalGlue());
268+ contentPane.add(chkPanel);
269+ }
316270
317- contentPane.add(btnPanel, BorderLayout.SOUTH);
271+ {
272+ Box btnsBox = Box.createHorizontalBox();
273+ btnsBox.add(btnRemoveRecent);
274+ btnsBox.add(btnRemoveWorkingSets);
275+ btnsBox.add(Box.createHorizontalGlue());
276+
277+ if (!Main.isLinuxOrMacOSX()) {
278+ btnsBox.add(btnOK);
279+ btnsBox.add(btnCancel);
280+ } else {
281+ btnsBox.add(btnCancel);
282+ btnsBox.add(btnOK);
283+ }
284+ btnsBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 24));
285+ contentPane.add(btnsBox);
286+ }
287+
288+ setTitle(strings.getProperty("title"));
289+ setResizable(true);
318290
319291 // フォルダのドロップによる入力を許可
320292 new DropTarget(this, new FileDropTarget() {
--- a/src/main/java/charactermanaj/ui/UkagakaConvertDialog.java
+++ b/src/main/java/charactermanaj/ui/UkagakaConvertDialog.java
@@ -3,6 +3,7 @@ package charactermanaj.ui;
33 import java.awt.BorderLayout;
44 import java.awt.Color;
55 import java.awt.Container;
6+import java.awt.Dimension;
67 import java.awt.GridBagConstraints;
78 import java.awt.GridBagLayout;
89 import java.awt.Insets;
@@ -38,6 +39,7 @@ import javax.swing.event.ChangeListener;
3839
3940 import charactermanaj.Main;
4041 import charactermanaj.graphics.io.UkagakaImageConverter;
42+import charactermanaj.ui.util.ScaleSupport;
4143 import charactermanaj.util.LocalizedResourcePropertyLoader;
4244
4345 /**
@@ -57,23 +59,23 @@ public class UkagakaConvertDialog extends JDialog {
5759 * キャプション
5860 */
5961 private TextField caption = new TextField();
60-
62+
6163 /**
6264 * キャンセル
6365 */
6466 private AbstractAction actCancel;
65-
67+
6668 /**
6769 * 保存(デフォルトアクション)
6870 */
6971 private AbstractAction actSave;
70-
72+
7173
7274 /**
7375 * プレビュー(PNG)
7476 */
7577 private SamplePicturePanel opaqueImagePanel = new SamplePicturePanel();
76-
78+
7779 /**
7880 * プレビュー(PNA)
7981 */
@@ -83,17 +85,17 @@ public class UkagakaConvertDialog extends JDialog {
8385 * 透過色キー表示ボックス
8486 */
8587 private ColorBox colorBox = new ColorBox();
86-
88+
8789 /**
8890 * エクスポート対象の元イメージ.
8991 */
9092 private BufferedImage originalImage;
91-
93+
9294 /**
9395 * 透過色をマニュアルとするか?
9496 */
9597 private boolean manualTransparentColorKey;
96-
98+
9799 /**
98100 * 透過キー自動モード
99101 */
@@ -103,27 +105,27 @@ public class UkagakaConvertDialog extends JDialog {
103105 * 透過キー手動選択モード
104106 */
105107 private JRadioButton radioManual;
106-
108+
107109 /**
108110 * 上書きモードチェックボックス
109111 */
110112 private JCheckBox chkOverwriteOption;
111-
113+
112114 /**
113115 * 終了コード
114116 */
115117 private Object result;
116-
118+
117119 /**
118120 * 保存ボタンアクションリスナ.<br>
119121 */
120122 private ActionListener saveActionListener;
121-
123+
122124 /**
123125 * 上書きオプションの表示フラグ
124126 */
125127 private boolean showOverwriteOption;
126-
128+
127129
128130 /**
129131 * 伺か用PNG/PNA出力設定ダイアログを構築する.
@@ -132,11 +134,11 @@ public class UkagakaConvertDialog extends JDialog {
132134 public UkagakaConvertDialog(JFrame parent) {
133135 this(parent, false);
134136 }
135-
137+
136138 /**
137139 * 伺か用PNG/PNA出力設定ダイアログを構築する.
138140 * @param parent 親フレーム
139- * @param overwriteOption 上書きオプションの表示
141+ * @param overwriteOption 上書きオプションの表示
140142 */
141143 public UkagakaConvertDialog(JFrame parent, boolean overwriteOption) {
142144 this(parent, null, overwriteOption);
@@ -146,7 +148,7 @@ public class UkagakaConvertDialog extends JDialog {
146148 * 伺か用PNG/PNA出力設定ダイアログを構築する.
147149 * @param parent 親フレーム
148150 * @param saveActionListener 保存ボタンアクション
149- * @param overwriteOption 上書きオプションの表示
151+ * @param overwriteOption 上書きオプションの表示
150152 */
151153 public UkagakaConvertDialog(JFrame parent, ActionListener saveActionListener, boolean overwriteOption) {
152154 super(parent, true);
@@ -163,7 +165,7 @@ public class UkagakaConvertDialog extends JDialog {
163165 result = null;
164166 }
165167 });
166-
168+
167169 try {
168170 initComponent();
169171
@@ -177,7 +179,7 @@ public class UkagakaConvertDialog extends JDialog {
177179 * コンポーネントの初期化
178180 */
179181 private void initComponent() {
180-
182+
181183 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
182184 .getLocalizedProperties(STRINGS_RESOURCE);
183185
@@ -197,7 +199,7 @@ public class UkagakaConvertDialog extends JDialog {
197199 onSave();
198200 }
199201 };
200-
202+
201203 JButton btnCancel = new JButton(actCancel);
202204 JButton btnSave = new JButton(actSave);
203205
@@ -207,18 +209,18 @@ public class UkagakaConvertDialog extends JDialog {
207209 contentPane.add(caption, BorderLayout.NORTH);
208210 caption.setEditable(false);
209211 caption.setVisible(false);
210-
212+
211213 JScrollPane opaqueSp = new JScrollPane(opaqueImagePanel);
212214 JScrollPane alphaSp = new JScrollPane(alphaImagePanel);
213215
214216 JPanel previewSpPane = new JPanel();
215217 BoxLayout boxlayout = new BoxLayout(previewSpPane, BoxLayout.LINE_AXIS);
216218 previewSpPane.setLayout(boxlayout);
217-
219+
218220 previewSpPane.add(opaqueSp);
219221 previewSpPane.add(Box.createHorizontalStrut(3));
220222 previewSpPane.add(alphaSp);
221-
223+
222224 previewSpPane.setBorder(BorderFactory.createCompoundBorder(
223225 BorderFactory.createTitledBorder(strings.getProperty("preview")),
224226 BorderFactory.createEmptyBorder(3, 3, 3, 3)
@@ -235,10 +237,10 @@ public class UkagakaConvertDialog extends JDialog {
235237 BorderFactory.createEmptyBorder(3, 3, 3, 3)
236238 ));
237239 centerPane.add(transparentColorPanel, BorderLayout.SOUTH);
238-
239-
240+
241+
240242 GridBagConstraints gbc = new GridBagConstraints();
241-
243+
242244 radioAuto = new JRadioButton(strings.getProperty("radio.auto"));
243245 radioAuto.addChangeListener(new ChangeListener() {
244246 public void stateChanged(ChangeEvent e) {
@@ -251,13 +253,13 @@ public class UkagakaConvertDialog extends JDialog {
251253 onChange(!radioAuto.isSelected());
252254 }
253255 });
254-
256+
255257 ButtonGroup btngroup = new ButtonGroup();
256258 btngroup.add(radioAuto);
257259 btngroup.add(radioManual);
258-
260+
259261 radioAuto.setSelected(!manualTransparentColorKey);
260-
262+
261263 gbc.gridx = 0;
262264 gbc.gridy = 0;
263265 gbc.gridheight = 1;
@@ -277,14 +279,14 @@ public class UkagakaConvertDialog extends JDialog {
277279 gbc.gridy = 0;
278280 transparentColorPanel.add(colorBox, gbc);
279281
280-
282+
281283 contentPane.add(centerPane, BorderLayout.CENTER);
282-
283-
284+
285+
284286 JPanel btnPanel = new JPanel();
285287 GridBagLayout gbl = new GridBagLayout();
286288 btnPanel.setLayout(gbl);
287-
289+
288290 gbc.gridx = 0;
289291 gbc.gridy = 0;
290292 gbc.gridheight = 1;
@@ -294,44 +296,50 @@ public class UkagakaConvertDialog extends JDialog {
294296 gbc.insets = new Insets(3, 3, 3, 3);
295297 gbc.anchor = GridBagConstraints.WEST;
296298 gbc.fill = GridBagConstraints.BOTH;
297-
299+
298300 chkOverwriteOption = new JCheckBox(strings.getProperty("chk.overwriteOriginalFile"));
299-
301+
300302 if (showOverwriteOption) {
301303 btnPanel.add(chkOverwriteOption, gbc);
302304
303305 } else {
304306 btnPanel.add(Box.createHorizontalGlue(), gbc);
305307 }
306-
308+
307309 gbc.gridx = Main.isLinuxOrMacOSX() ? 2 : 1;
308310 gbc.gridy = 0;
309311 gbc.weightx = 0.;
310312 btnPanel.add(btnSave, gbc);
311-
313+
312314 gbc.gridx = Main.isLinuxOrMacOSX() ? 1 : 2;
313315 gbc.gridy = 0;
314316 btnPanel.add(btnCancel, gbc);
315-
317+
316318 btnPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 45));
317-
319+
318320 contentPane.add(btnPanel, BorderLayout.SOUTH);
319-
321+
320322 JRootPane rootPane = getRootPane();
321323 InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
322324 ActionMap am = rootPane.getActionMap();
323325 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "closeExportWizDialog");
324326 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeExportWizDialog");
325-
327+
326328 am.put("closeExportWizDialog", actCancel);
327-
329+
328330 rootPane.setDefaultButton(btnSave);
329-
331+
330332 rootPane.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
331333
332- setSize(450, 450);
334+ Dimension dim = new Dimension(450, 450);
335+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
336+ if (scaleSupport != null) {
337+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
338+ dim = scaleSupport.manualScaled(dim);
339+ }
340+ setSize(dim);
333341 setLocationRelativeTo(getParent());
334-
342+
335343 // colorBoxの色変更イベントのハンドル
336344 colorBox.addActionListener(new ActionListener() {
337345 public void actionPerformed(ActionEvent e) {
@@ -339,7 +347,7 @@ public class UkagakaConvertDialog extends JDialog {
339347 }
340348 });
341349 }
342-
350+
343351 /**
344352 * 出力するイメージを設定する.
345353 * @param img イメージ(TYPE_INT_ARGBのみ)
@@ -352,7 +360,7 @@ public class UkagakaConvertDialog extends JDialog {
352360 if (img.getType() != BufferedImage.TYPE_INT_ARGB) {
353361 throw new IllegalArgumentException("TYPE_INT_ARGB以外は指定できません。");
354362 }
355-
363+
356364 if (colorKey == null) {
357365 colorKey = Color.GREEN;
358366 }
@@ -362,15 +370,15 @@ public class UkagakaConvertDialog extends JDialog {
362370
363371 rebuildImage();
364372 }
365-
373+
366374 public BufferedImage getOpaqueImage() {
367375 return opaqueImagePanel.getSamplePictrue();
368376 }
369-
377+
370378 public BufferedImage getAlphaImage() {
371379 return alphaImagePanel.getSamplePictrue();
372380 }
373-
381+
374382 public void setAutoTransparentColor(boolean mode) {
375383 if (mode) {
376384 radioAuto.setSelected(true);
@@ -381,55 +389,55 @@ public class UkagakaConvertDialog extends JDialog {
381389 radioAuto.setSelected(false);
382390 }
383391 }
384-
392+
385393 public Color getTransparentColorKey() {
386394 return colorBox.getColorKey();
387395 }
388-
396+
389397 public void setTransparentColorKey(Color colorKey) {
390398 colorBox.setColorKey(colorKey);
391399 }
392-
400+
393401 public boolean isAutoTransparentColor() {
394402 return radioAuto.isSelected();
395403 }
396-
404+
397405 public boolean isOverwriteOriginalFile() {
398406 return chkOverwriteOption.isSelected();
399407 }
400-
408+
401409 public void setOverwriteOriginalFile(boolean overwriteOriginalFile) {
402410 chkOverwriteOption.setSelected(overwriteOriginalFile);
403411 }
404-
412+
405413 protected void onClose() {
406414 result = null;
407415 dispose();
408416 }
409-
417+
410418 protected void onSave() {
411419 if (saveActionListener != null) {
412420 ActionEvent e = new ActionEvent(this, 0, "save");
413421 saveActionListener.actionPerformed(e);
414422 }
415423 }
416-
424+
417425 public void setSaveActionListener(ActionListener saveActionListener) {
418426 this.saveActionListener = saveActionListener;
419427 }
420-
428+
421429 public ActionListener getSaveActionListener() {
422430 return saveActionListener;
423431 }
424-
432+
425433 public Object getResult() {
426434 return result;
427435 }
428-
436+
429437 public void setResult(Object result) {
430- this.result = result;
438+ this.result = result;
431439 }
432-
440+
433441 public void setCaption(String text) {
434442 if (text == null || text.length() == 0) {
435443 caption.setText("");
@@ -440,11 +448,11 @@ public class UkagakaConvertDialog extends JDialog {
440448 caption.setVisible(true);
441449 }
442450 }
443-
451+
444452 public String getCaption() {
445453 return caption.getText();
446454 }
447-
455+
448456 /**
449457 * 透過色のマニュアル選択.<br>
450458 */
@@ -465,7 +473,7 @@ public class UkagakaConvertDialog extends JDialog {
465473 rebuildImage();
466474 }
467475 }
468-
476+
469477 /**
470478 * 伺か用のPNG/PNA画像を生成してプレビューに設定します.<br>
471479 */
@@ -476,16 +484,16 @@ public class UkagakaConvertDialog extends JDialog {
476484 UkagakaImageConverter conv = UkagakaImageConverter.getInstance();
477485
478486 BufferedImage pna = conv.createUkagakaPNA(originalImage);
479-
487+
480488 Color transparentColorKey = null;
481489 if (manualTransparentColorKey) {
482490 transparentColorKey = colorBox.getColorKey();
483491 } else {
484492 transparentColorKey = conv.detectTransparentColorKey(originalImage);
485493 }
486-
494+
487495 BufferedImage png = conv.createUkagakaPNG(originalImage, transparentColorKey);
488-
496+
489497 opaqueImagePanel.setSamplePicture(png);
490498 alphaImagePanel.setSamplePicture(pna);
491499 }
--- a/src/main/java/charactermanaj/ui/WallpaperDialog.java
+++ b/src/main/java/charactermanaj/ui/WallpaperDialog.java
@@ -46,6 +46,7 @@ import charactermanaj.graphics.io.ImagePreviewFileChooser;
4646 import charactermanaj.ui.model.PredefinedWallpaper;
4747 import charactermanaj.ui.model.WallpaperInfo;
4848 import charactermanaj.ui.model.WallpaperInfo.WallpaperResourceType;
49+import charactermanaj.ui.util.ScaleSupport;
4950 import charactermanaj.util.LocalizedMessageComboBoxRender;
5051 import charactermanaj.util.LocalizedResourcePropertyLoader;
5152
@@ -71,49 +72,49 @@ public class WallpaperDialog extends JDialog {
7172 * 壁紙情報
7273 */
7374 private WallpaperInfo wallpaperInfo = new WallpaperInfo();
74-
75-
75+
76+
7677 /**
7778 * 選択なしラジオ
7879 */
7980 private JRadioButton radioNone;
80-
81+
8182 /**
8283 * ファイルから選択ラジオ
8384 */
8485 private JRadioButton radioFile;
85-
86+
8687 /**
8788 * 定義済みから選択ラジオ
8889 */
8990 private JRadioButton radioPredefined;
90-
91+
9192 /**
9293 * 定義済み壁紙リスト
9394 */
9495 private JList listPredefinedWallpapers;
95-
96+
9697 /**
9798 * 背景画像の透過率
9899 */
99100 private JSpinner spinnerAlpha;
100-
101+
101102 /**
102103 * 選択ファイルフィールド
103104 */
104105 private JTextField txtFile;
105-
106+
106107 /**
107108 * ファイルを選択アクション
108109 */
109110 private AbstractAction actChooseFile;
110-
111+
111112 /**
112113 * 背景色選択コンポーネント
113114 */
114115 private ColorBox colorBox;
115116
116-
117+
117118 /**
118119 * コンストラクタ
119120 * @param parent 親フレーム
@@ -127,16 +128,16 @@ public class WallpaperDialog extends JDialog {
127128 onCancel();
128129 };
129130 });
130-
131+
131132 initPredefinedWallpapers();
132133 initComponent();
133-
134+
134135 } catch (RuntimeException ex) {
135136 dispose();
136137 throw ex;
137138 }
138139 }
139-
140+
140141 /**
141142 * 定義済み壁紙リストを初期化する.<br>
142143 * 既に初期化済みであれば何もしない.<br>
@@ -147,7 +148,7 @@ public class WallpaperDialog extends JDialog {
147148 }
148149 predefinedWallpapers.addAll(PredefinedWallpaper.getPredefinedWallpapers());
149150 }
150-
151+
151152 /**
152153 * このダイアログのコンポーネントを初期化します.<br>
153154 */
@@ -156,7 +157,7 @@ public class WallpaperDialog extends JDialog {
156157 .getLocalizedProperties(WallpaperDialog.STRINGS_RESOURCE);
157158
158159 setTitle(strings.getProperty("title"));
159-
160+
160161 Container contentPane = getContentPane();
161162 contentPane.setLayout(new BorderLayout(3, 3));
162163 getRootPane().setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
@@ -164,15 +165,21 @@ public class WallpaperDialog extends JDialog {
164165 JPanel wallpaperPanel = createWallpaperChoosePanel(strings);
165166 JPanel bgcolorPanel = createBgColorPanel(strings);
166167 JPanel btnPanel = createButtonPanel(strings);
167-
168+
168169 contentPane.add(bgcolorPanel, BorderLayout.NORTH);
169170 contentPane.add(wallpaperPanel, BorderLayout.CENTER);
170171 contentPane.add(btnPanel, BorderLayout.SOUTH);
171-
172- setSize(400, 350);
172+
173+ Dimension dim = new Dimension(400, 350);
174+ ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
175+ if (scaleSupport != null) {
176+ // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
177+ dim = scaleSupport.manualScaled(dim);
178+ }
179+ setSize(dim);
173180 setLocationRelativeTo(getParent());
174181 }
175-
182+
176183 private JPanel createButtonPanel(Properties strings) {
177184 JPanel btnPanel = new JPanel();
178185
@@ -188,14 +195,14 @@ public class WallpaperDialog extends JDialog {
188195 onCancel();
189196 }
190197 };
191-
198+
192199 JButton btnOK = new JButton(actOK);
193200 JButton btnCancel = new JButton(actCancel);
194201
195202 BoxLayout bl = new BoxLayout(btnPanel, BoxLayout.LINE_AXIS);
196203 btnPanel.setLayout(bl);
197204 btnPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 45));
198-
205+
199206 btnPanel.add(Box.createHorizontalGlue());
200207 if (Main.isLinuxOrMacOSX()) {
201208 btnPanel.add(btnCancel);
@@ -209,11 +216,11 @@ public class WallpaperDialog extends JDialog {
209216 // Enter/Returnキーを既定ボタンにする.
210217 JRootPane rootPane = getRootPane();
211218 rootPane.setDefaultButton(btnOK);
212-
219+
213220 // CTRL-Wでウィンドウを非表示にする. (ESCでは非表示にしない)
214221 InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
215222 ActionMap am = rootPane.getActionMap();
216-
223+
217224 Toolkit tk = Toolkit.getDefaultToolkit();
218225 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "closeWallpaperDialog");
219226 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeWallpaperDialog");
@@ -221,7 +228,7 @@ public class WallpaperDialog extends JDialog {
221228
222229 return btnPanel;
223230 }
224-
231+
225232 private JPanel createBgColorPanel(Properties strings) {
226233 JPanel bgcolorPanel = new JPanel();
227234
@@ -232,12 +239,12 @@ public class WallpaperDialog extends JDialog {
232239
233240 GridBagLayout gbl = new GridBagLayout();
234241 bgcolorPanel.setLayout(gbl);
235-
242+
236243 colorBox = new ColorBox();
237244 colorBox.getColorDisplayPanel().setPreferredSize(new Dimension(48, 20));
238245
239246 GridBagConstraints gbc = new GridBagConstraints();
240-
247+
241248 gbc.ipadx = 0;
242249 gbc.ipady = 0;
243250 gbc.insets = new Insets(0, 0, 0, 0);
@@ -245,7 +252,7 @@ public class WallpaperDialog extends JDialog {
245252 gbc.gridheight = 1;
246253 gbc.anchor = GridBagConstraints.CENTER;
247254 gbc.fill = GridBagConstraints.NONE;
248-
255+
249256 bgcolorPanel.add(colorBox, gbc);
250257
251258 return bgcolorPanel;
@@ -253,25 +260,25 @@ public class WallpaperDialog extends JDialog {
253260
254261 private JPanel createWallpaperChoosePanel(Properties strings) {
255262 JPanel wallpaperPanel = new JPanel();
256-
263+
257264 wallpaperPanel.setBorder(BorderFactory.createTitledBorder(strings.getProperty("group.wallpaper")));
258265
259266 GridBagLayout gbl = new GridBagLayout();
260267 wallpaperPanel.setLayout(gbl);
261-
268+
262269 radioNone = new JRadioButton(strings.getProperty("radio.none"));
263270 radioFile = new JRadioButton(strings.getProperty("radio.file"));
264271 radioPredefined = new JRadioButton(strings.getProperty("radio.predefined"));
265-
272+
266273 ButtonGroup btnGroup = new ButtonGroup();
267274 btnGroup.add(radioNone);
268275 btnGroup.add(radioFile);
269276 btnGroup.add(radioPredefined);
270-
277+
271278 radioNone.setSelected(true);
272-
279+
273280 txtFile = new JTextField();
274-
281+
275282 actChooseFile = new AbstractAction(strings.getProperty("btn.chooseFile")) {
276283 private static final long serialVersionUID = 1L;
277284 public void actionPerformed(ActionEvent e) {
@@ -283,13 +290,13 @@ public class WallpaperDialog extends JDialog {
283290 listPredefinedWallpapers = new JList(predefinedWallpapers
284291 .toArray(new PredefinedWallpaper[predefinedWallpapers.size()]));
285292 listPredefinedWallpapers.setCellRenderer(new LocalizedMessageComboBoxRender(strings));
286-
293+
287294 SpinnerNumberModel alphaSpModel = new SpinnerNumberModel(100, 0, 100, 1);
288295 spinnerAlpha = new JSpinner(alphaSpModel);
289-
290-
296+
297+
291298 GridBagConstraints gbc = new GridBagConstraints();
292-
299+
293300 gbc.ipadx = 0;
294301 gbc.ipady = 0;
295302 gbc.insets = new Insets(0, 0, 0, 0);
@@ -297,14 +304,14 @@ public class WallpaperDialog extends JDialog {
297304 gbc.gridheight = 1;
298305 gbc.anchor = GridBagConstraints.WEST;
299306 gbc.fill = GridBagConstraints.BOTH;
300-
307+
301308 gbc.gridx = 0;
302309 gbc.gridy = 0;
303310 gbc.gridwidth = 3;
304311 gbc.weightx = 0.;
305312
306313 wallpaperPanel.add(radioNone, gbc);
307-
314+
308315 gbc.gridx = 0;
309316 gbc.gridy = 1;
310317 gbc.gridwidth = 3;
@@ -316,23 +323,23 @@ public class WallpaperDialog extends JDialog {
316323 gbc.gridy = 2;
317324 gbc.gridwidth = 1;
318325 gbc.weightx = 0.;
319-
326+
320327 wallpaperPanel.add(Box.createHorizontalStrut(20), gbc);
321-
328+
322329 gbc.gridx = 1;
323330 gbc.gridy = 2;
324331 gbc.gridwidth = 1;
325332 gbc.weightx = 1.;
326-
333+
327334 wallpaperPanel.add(txtFile, gbc);
328335
329336 gbc.gridx = 2;
330337 gbc.gridy = 2;
331338 gbc.gridwidth = 1;
332339 gbc.weightx = 0.;
333-
340+
334341 wallpaperPanel.add(btnChooseFile, gbc);
335-
342+
336343 gbc.gridx = 0;
337344 gbc.gridy = 3;
338345 gbc.gridwidth = 3;
@@ -345,25 +352,25 @@ public class WallpaperDialog extends JDialog {
345352 gbc.gridwidth = 2;
346353 gbc.weightx = 1.;
347354 gbc.weighty = 1.;
348-
355+
349356 wallpaperPanel.add(new JScrollPane(listPredefinedWallpapers), gbc);
350-
357+
351358 gbc.gridx = 0;
352359 gbc.gridy = 5;
353360 gbc.gridwidth = 3;
354361 gbc.weightx = 0.;
355362 gbc.weighty = 0.;
356363 gbc.insets = new Insets(5, 0, 0, 0);
357-
364+
358365 wallpaperPanel.add(new JLabel(
359366 strings.getProperty("label.wallpaperImageAlpha")), gbc);
360-
361-
367+
368+
362369 JPanel alphaPanel = new JPanel(new BorderLayout(3, 3));
363370 alphaPanel.setBorder(BorderFactory.createEmptyBorder(3, 0, 3, 0));
364371 alphaPanel.add(spinnerAlpha, BorderLayout.CENTER);
365372 alphaPanel.add(new JLabel("%"), BorderLayout.EAST);
366-
373+
367374 gbc.gridx = 1;
368375 gbc.gridy = 6;
369376 gbc.gridwidth = 2;
@@ -375,7 +382,7 @@ public class WallpaperDialog extends JDialog {
375382 gbc.anchor = GridBagConstraints.WEST;
376383
377384 wallpaperPanel.add(alphaPanel, gbc);
378-
385+
379386 // リスナ
380387 listPredefinedWallpapers.addListSelectionListener(new ListSelectionListener() {
381388 public void valueChanged(ListSelectionEvent e) {
@@ -388,7 +395,7 @@ public class WallpaperDialog extends JDialog {
388395
389396 protected void onChooseFile() {
390397 File selectedFile = wallpaperInfo.getFile();
391-
398+
392399 final JFileChooser fileChooser = new ImagePreviewFileChooser();
393400 fileChooser.setSelectedFile(selectedFile);
394401
@@ -400,16 +407,16 @@ public class WallpaperDialog extends JDialog {
400407 txtFile.setText(selectedFile == null ? "" : selectedFile.getPath());
401408 radioFile.setSelected(selectedFile != null);
402409 }
403-
410+
404411 /**
405412 * 壁紙情報インスタンスの内容でコンポーネントを設定する.
406413 */
407414 protected void applyByWallpaperInfo() {
408-
415+
409416 // ファイル
410417 File imageFile = wallpaperInfo.getFile();
411418 txtFile.setText(imageFile == null ? "" : imageFile.getPath());
412-
419+
413420 // リソース
414421 PredefinedWallpaper selectedPredefinedWp = null;
415422 String resource = wallpaperInfo.getResource();
@@ -419,20 +426,20 @@ public class WallpaperDialog extends JDialog {
419426 }
420427 }
421428 listPredefinedWallpapers.setSelectedValue(selectedPredefinedWp, true);
422-
429+
423430 // 透過率
424431 int alphaInt = (int)(wallpaperInfo.getAlpha() * 100);
425432 spinnerAlpha.setValue(alphaInt);
426-
433+
427434 // 背景色
428435 Color bgColor = wallpaperInfo.getBackgroundColor();
429436 colorBox.setColorKey(bgColor);
430-
437+
431438 // タイプ
432439 WallpaperResourceType typ = wallpaperInfo.getType();
433440 if (typ == WallpaperResourceType.FILE) {
434441 radioFile.setSelected(true);
435-
442+
436443 } else if (typ == WallpaperResourceType.PREDEFINED) {
437444 radioPredefined.setSelected(true);
438445
@@ -458,7 +465,7 @@ public class WallpaperDialog extends JDialog {
458465 } else if (radioPredefined.isSelected()) {
459466 // リソース選択
460467 typ = WallpaperResourceType.PREDEFINED;
461-
468+
462469 } else {
463470 // それ以外は選択なし
464471 typ = WallpaperResourceType.NONE;
@@ -474,31 +481,31 @@ public class WallpaperDialog extends JDialog {
474481 }
475482 }
476483 wallpaperInfo.setFile(selectedFile);
477-
484+
478485 // 定義済みリソースの現在の選択
479486 PredefinedWallpaper predefinedWp =
480487 (PredefinedWallpaper) listPredefinedWallpapers.getSelectedValue();
481488 wallpaperInfo.setResource(predefinedWp == null ?
482489 null : predefinedWp.getResource());
483-
490+
484491 // タイプの設定
485492 wallpaperInfo.setType(typ);
486-
493+
487494 // 背景画像の透過率
488495 int alphaInt = (Integer) spinnerAlpha.getValue();
489496 float alpha = (float) alphaInt / 100.f;
490497 wallpaperInfo.setAlpha(alpha);
491-
498+
492499 // 背景色
493500 Color bgColor = colorBox.getColorKey();
494501 wallpaperInfo.setBackgroundColor(bgColor);
495-
502+
496503 return wallpaperInfo;
497504 }
498-
505+
499506 protected void onOK() {
500507 WallpaperInfo wallpaperInfo = createWallpaperInfo();
501-
508+
502509 if (!checkValidate(wallpaperInfo)) {
503510 return;
504511 }
@@ -506,12 +513,12 @@ public class WallpaperDialog extends JDialog {
506513 this.wallpaperInfo = wallpaperInfo;
507514 dispose();
508515 }
509-
516+
510517 protected void onCancel() {
511518 wallpaperInfo = null;
512519 dispose();
513520 }
514-
521+
515522 protected boolean checkValidate(WallpaperInfo wallpaperInfo) {
516523 String messageid = null;
517524 WallpaperResourceType typ = wallpaperInfo.getType();
@@ -530,7 +537,7 @@ public class WallpaperDialog extends JDialog {
530537 messageid = "error.require.resource";
531538 }
532539 }
533-
540+
534541 if (messageid != null) {
535542 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
536543 .getLocalizedProperties(WallpaperDialog.STRINGS_RESOURCE);
@@ -538,21 +545,21 @@ public class WallpaperDialog extends JDialog {
538545 String message = strings.getProperty(messageid);
539546 JOptionPane.showMessageDialog(this, message, "ERROR", JOptionPane.ERROR_MESSAGE);
540547 }
541-
548+
542549 return messageid == null;
543550 }
544-
551+
545552 public void setWallpaperInfo(WallpaperInfo wallpaperInfo) {
546553 if (wallpaperInfo == null) {
547554 wallpaperInfo = new WallpaperInfo();
548555 }
549556 this.wallpaperInfo = wallpaperInfo;
550557 }
551-
558+
552559 public WallpaperInfo getWallpaperInfo() {
553560 return wallpaperInfo;
554561 }
555-
562+
556563 /**
557564 * ダイアログを表示し、その結果を返す.<br>
558565 * キャンセルされた場合はnullが返される.<br>
--- /dev/null
+++ b/src/main/java/charactermanaj/ui/util/ScaleSupport.java
@@ -0,0 +1,90 @@
1+package charactermanaj.ui.util;
2+
3+import java.awt.Component;
4+import java.awt.Dimension;
5+import java.awt.GraphicsConfiguration;
6+import java.awt.GraphicsDevice;
7+import java.awt.GraphicsEnvironment;
8+import java.awt.Toolkit;
9+import java.awt.geom.AffineTransform;
10+
11+/**
12+ * スクリーンのスケールを取得する。
13+ *
14+ * Java8であれば自動スケールがかかっていないので、マニュアルでスケール倍して座標を補正する。
15+ * Java11であれば自動スケールがかかっている。
16+ */
17+public class ScaleSupport {
18+
19+ private static final float scale;
20+
21+ private double scaleX;
22+
23+ private double scaleY;
24+
25+ private double manualScaleX;
26+
27+ private double manualScaleY;
28+
29+ static {
30+ Toolkit tk = Toolkit.getDefaultToolkit();
31+ int resolution = tk.getScreenResolution();
32+
33+ float dpi = System.getProperty("os.name").startsWith("Windows") ? 96f : 72f;
34+ scale = resolution / dpi;
35+ }
36+
37+ private ScaleSupport(double scaleX, double scaleY) {
38+ this.scaleX = scaleX;
39+ this.scaleY = scaleY;
40+ manualScaleX = scale / scaleX;
41+ manualScaleY = scale / scaleX;
42+ }
43+
44+ /**
45+ * コンポーネントのグラフィクス設定からスケールを取得する。
46+ * まだ画面に関連付けられていない場合はnullを返す。
47+ * @param comp
48+ * @return
49+ */
50+ public static ScaleSupport getInstance(Component comp) {
51+ GraphicsConfiguration gconf = comp.getGraphicsConfiguration();
52+ if (gconf == null) {
53+ return null;
54+ }
55+ return getInstance(gconf);
56+ }
57+
58+ public static ScaleSupport getDefault() {
59+ GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
60+ GraphicsDevice gdev = genv.getDefaultScreenDevice();
61+ return getInstance(gdev.getDefaultConfiguration());
62+ }
63+
64+ public static ScaleSupport getInstance(GraphicsConfiguration gconf) {
65+ AffineTransform trans = gconf.getDefaultTransform();
66+ double scaleX = trans.getScaleX();
67+ double scaleY = trans.getScaleY();
68+ return new ScaleSupport(scaleX, scaleY);
69+ }
70+
71+ public double getDefaultScaleX() {
72+ return scaleX;
73+ }
74+
75+ public double getDefaultScaleY() {
76+ return scaleY;
77+ }
78+
79+ public double getManualScaleX() {
80+ return manualScaleX;
81+ }
82+
83+ public double getManualScaleY() {
84+ return manualScaleY;
85+ }
86+
87+ public Dimension manualScaled(Dimension dim) {
88+ return new Dimension((int) (dim.getWidth() * manualScaleX), (int) (dim.getHeight() * manualScaleY));
89+ }
90+}
\ No newline at end of file
--- a/src/main/java/charactermanaj/util/ErrorMessageHelper.java
+++ b/src/main/java/charactermanaj/util/ErrorMessageHelper.java
@@ -20,6 +20,8 @@ import javax.swing.JOptionPane;
2020 import javax.swing.JScrollPane;
2121 import javax.swing.JTextArea;
2222
23+import charactermanaj.ui.util.ScaleSupport;
24+
2325 /**
2426 * 例外を表示するダイアログ.<br>
2527 * ログにも記録される.<br>
@@ -77,7 +79,6 @@ public final class ErrorMessageHelper {
7779 JOptionPane pane = new JOptionPane(scr, JOptionPane.ERROR_MESSAGE);
7880
7981 Window window = getWindowForComponent(parent);
80- System.out.println("window=" + window);
8182
8283 final JDialog dialog;
8384 String title = "ERROR";
@@ -95,7 +96,10 @@ public final class ErrorMessageHelper {
9596 contentPane.add(pane, BorderLayout.CENTER);
9697 dialog.setResizable(true);
9798
98- dialog.pack();
99+ ScaleSupport scaleSupport = ScaleSupport.getInstance(dialog);
100+ Dimension wnddim = dialog.getPreferredSize();
101+ wnddim = scaleSupport.manualScaled(wnddim);
102+ dialog.setSize(wnddim);
99103 dialog.setLocationRelativeTo(parent);
100104
101105 pane.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, new PropertyChangeListener() {
Show on old repository browser