設定をカテゴリーごとに分割 developer.android.com
あなた:
下記のコードをAndroidのpreferenceに書き換えて
//////////////////////////////////////////////////////////////// //Tab 変換 //////////////////////////////////////////////////////////////// tabPanel = new JPanel(); tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.Y_AXIS)); jTabbedPane.setPreferredSize(new Dimension(1920, 220)); jTabbedPane.addTab("変換 ", epubIcon, tabPanel); //////////////////////////////// //表題 //////////////////////////////// panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setMinimumSize(panelSize); panel.setMaximumSize(panelSize); panel.setPreferredSize(panelSize); panel.setBorder(padding4H2V); tabPanel.add(panel); label = new JLabel("表題: "); panel.add(label); label = new JLabel("本文内"); label.setBorder(padding2H); panel.add(label); jComboTitle = new JComboBox<String>(BookInfo.TitleType.titleTypeNames); jComboTitle.setFocusable(false); jComboTitle.setMaximumSize(new Dimension(200, 22)); jComboTitle.setBorder(padding0); ((JLabel)jComboTitle.getRenderer()).setBorder(padding2H); panel.add(jComboTitle); //入力ファイル名優先 jCheckPubFirst = new JCheckBox("先頭が発行者"); jCheckPubFirst.setFocusPainted(false); panel.add(jCheckPubFirst); //入力ファイル名優先 panel.add(new JLabel(" ")); jCheckUseFileName = new JCheckBox("ファイル名優先 "); jCheckUseFileName.setFocusPainted(false); panel.add(jCheckUseFileName); //////////////////////////////// //表紙 //////////////////////////////// panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setMinimumSize(panelSize); panel.setMaximumSize(panelSize); panel.setPreferredSize(panelSize); panel.setBorder(padding4H2V); tabPanel.add(panel); //表紙 label = new JLabel("表紙: "); panel.add(label); jTextMaxCoverLine = new JTextField(10); jTextMaxCoverLine.setToolTipText("先頭の挿絵に利用する画像注記を取得する最大行数 0なら制限なし"); jTextMaxCoverLine.setHorizontalAlignment(JTextField.RIGHT); jTextMaxCoverLine.setMinimumSize(text4); jTextMaxCoverLine.setMaximumSize(text4); jTextMaxCoverLine.setPreferredSize(text4); jTextMaxCoverLine.addFocusListener(new TextSelectFocusListener(jTextMaxCoverLine)); jTextMaxCoverLine.setInputVerifier(new IntegerInputVerifier(10, 0, 9999)); panel.add(jTextMaxCoverLine); jLabelMaxCoverLine = new JLabel("行目までの"); jLabelMaxCoverLine.setToolTipText(jTextMaxCoverLine.getToolTipText()); jLabelMaxCoverLine.setBorder(padding2H); panel.add(jLabelMaxCoverLine); jComboCover = new JComboBox<String>(new String[]{"[先頭の挿絵]", "[入力ファイル名と同じ画像(png,jpg)]", "[表紙無し]", "http://","[SVG表紙生成]"}); jComboCover.setEditable(true); jComboCover.setPreferredSize(new Dimension(320, 24)); jComboCover.addActionListener(arg0 -> { boolean visible = jComboCover.getSelectedIndex() == 0; jTextMaxCoverLine.setVisible(visible); jLabelMaxCoverLine.setVisible(visible); }); panel.add(jComboCover); new DropTarget(jComboCover.getEditor().getEditorComponent(), DnDConstants.ACTION_COPY_OR_MOVE, new DropCoverListener(), true); boolean visible = jComboCover.getSelectedIndex() == 0; jTextMaxCoverLine.setVisible(visible); jLabelMaxCoverLine.setVisible(visible); jButtonCover = new JButton("選択"); jButtonCover.setBorder(padding3); jButtonCover.setIcon(new ImageIcon(Objects.requireNonNull(AozoraEpub3Applet.class.getResource("images/cover.png")))); jButtonCover.setFocusPainted(false); jButtonCover.addActionListener(new CoverChooserListener(this)); panel.add(jButtonCover); jCheckCoverHistory = new JCheckBox("表紙履歴利用", true); jCheckCoverHistory.setToolTipText("前回の変換(またはスキップ)で設定した表紙を利用します ※履歴は再起動時に初期化されます"); jCheckCoverHistory.setFocusPainted(false); panel.add(jCheckCoverHistory); panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setMinimumSize(panelSize); panel.setMaximumSize(panelSize); panel.setPreferredSize(panelSize); panel.setBorder(padding4H2V); tabPanel.add(panel); //ページ出力 label = new JLabel("ページ出力:"); panel.add(label); jCheckCoverPage = new JCheckBox("表紙画像 ", true); jCheckCoverPage.setFocusPainted(false); panel.add(jCheckCoverPage); //左右中央 jCheckTitlePage = new JCheckBox("表題", true); jCheckTitlePage.setToolTipText("表題を単独のページで出力します。チェック無し時は表題等は出力されません"); jCheckTitlePage.setFocusPainted(false); panel.add(jCheckTitlePage); label = new JLabel("("); panel.add(label); buttonGroup = new ButtonGroup(); jRadioTitleNormal = new JRadioButton("本文内 "); jRadioTitleNormal.setToolTipText("別ページ処理せずに本文中に表題等を出力します。 目次は表題前に出力されます"); jRadioTitleNormal.setBorder(padding0); jRadioTitleNormal.setIconTextGap(1); panel.add(jRadioTitleNormal); buttonGroup.add(jRadioTitleNormal); jRadioTitleMiddle = new JRadioButton("中央 ", true); jRadioTitleMiddle.setToolTipText("中央寄せの表題ページを出力します"); jRadioTitleMiddle.setBorder(padding0); jRadioTitleMiddle.setIconTextGap(1); panel.add(jRadioTitleMiddle); buttonGroup.add(jRadioTitleMiddle); jRadioTitleHorizontal = new JRadioButton("横書き"); jRadioTitleHorizontal.setToolTipText("横書きの表題ページを出力します"); jRadioTitleHorizontal.setBorder(padding0); jRadioTitleHorizontal.setIconTextGap(1); panel.add(jRadioTitleHorizontal); buttonGroup.add(jRadioTitleHorizontal); label = new JLabel(") "); panel.add(label); jCheckTocPage = new JCheckBox("目次"); jCheckTocPage.setToolTipText("目次ページを表題ページの次に追加します"); jCheckTocPage.setFocusPainted(false); panel.add(jCheckTocPage); label = new JLabel("("); panel.add(label); buttonGroup = new ButtonGroup(); jRadioTocV = new JRadioButton("縦 ", true); jRadioTocV.setFocusPainted(false); jRadioTocV.setIconTextGap(2); jRadioTocV.setBorder(padding0); panel.add(jRadioTocV); buttonGroup.add(jRadioTocV); jRadioTocH = new JRadioButton("横"); jRadioTocH.setFocusPainted(false); jRadioTocH.setIconTextGap(2); jRadioTocH.setBorder(padding0); panel.add(jRadioTocH); buttonGroup.add(jRadioTocH); label = new JLabel(")"); panel.add(label);
ChatGPT:
AndroidのPreference画面は、PreferenceFragmentCompatを使って構築するのが一般的です。Swingのように細かくレイアウトを組むのではなく、XMLで定義し、設定項目(CheckBoxPreference、EditTextPreference、ListPreferenceなど)で構成されます。
以下は、あなたのSwing UIをAndroidのPreferenceに書き換えた例です(要素を対応させたサンプル):
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 表題 --> <PreferenceCategory android:title="表題"> <ListPreference android:key="title_type" android:title="表題の種類" android:entries="@array/title_type_names" android:entryValues="@array/title_type_values" android:defaultValue="default" /> <CheckBoxPreference android:key="pub_first" android:title="先頭が発行者" android:defaultValue="false" /> <CheckBoxPreference android:key="use_filename" android:title="ファイル名優先" android:defaultValue="false" /> </PreferenceCategory> <!-- 表紙 --> <PreferenceCategory android:title="表紙"> <EditTextPreference android:key="max_cover_lines" android:title="最大行数" android:dialogTitle="画像注記の取得最大行数" android:defaultValue="0" android:inputType="number" /> <ListPreference android:key="cover_mode" android:title="表紙設定" android:entries="@array/cover_options" android:entryValues="@array/cover_options_values" android:defaultValue="0" /> <CheckBoxPreference android:key="use_cover_history" android:title="表紙履歴利用" android:defaultValue="true" android:summary="前回の表紙を利用。履歴は再起動で初期化されます。" /> </PreferenceCategory> <!-- ページ出力 --> <PreferenceCategory android:title="ページ出力"> <CheckBoxPreference android:key="output_cover_page" android:title="表紙画像を出力" android:defaultValue="true" /> <CheckBoxPreference android:key="output_title_page" android:title="表題ページを出力" android:defaultValue="true" /> <ListPreference android:key="title_page_style" android:title="表題ページスタイル" android:entries="@array/title_page_styles" android:entryValues="@array/title_page_styles_values" android:defaultValue="middle" /> <CheckBoxPreference android:key="output_toc" android:title="目次ページを出力" android:defaultValue="true" /> <ListPreference android:key="toc_style" android:title="目次スタイル" android:entries="@array/toc_styles" android:entryValues="@array/toc_styles_values" android:defaultValue="vertical" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="title_type_names"> <item>本文内</item> <item>別ページ</item> </string-array> <string-array name="title_type_values"> <item>inline</item> <item>separate</item> </string-array> <string-array name="cover_options"> <item>先頭の挿絵</item> <item>ファイル名と同じ画像</item> <item>表紙無し</item> <item>http://</item> <item>SVG表紙生成</item> </string-array> <string-array name="cover_options_values"> <item>0</item> <item>1</item> <item>2</item> <item>3</item> <item>4</item> </string-array> <string-array name="title_page_styles"> <item>本文内</item> <item>中央</item> <item>横書き</item> </string-array> <string-array name="title_page_styles_values"> <item>normal</item> <item>middle</item> <item>horizontal</item> </string-array> <string-array name="toc_styles"> <item>縦</item> <item>横</item> </string-array> <string-array name="toc_styles_values"> <item>vertical</item> <item>horizontal</item> </string-array> </resources>
public class ConvertPreferenceFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.pref_convert, rootKey); } }
必要であれば、このUIに対してカスタムな動作(たとえば、ListPreferenceの選択肢によって他の要素の表示/非表示を切り替えるなど)をJava/Kotlinコードで追加できます。
続きの変換も必要であれば、教えてください!
あなた:
下記のコードをAndroidのpreferenceに書き換えて
////////////////////////////////
//出力ファイル設定
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setMinimumSize(panelSize);
panel.setMaximumSize(panelSize);
panel.setPreferredSize(panelSize);
panel.setBorder(padding4H2V);
tabPanel.add(panel);
//拡張子
label = new JLabel("拡張子: ");
panel.add(label);
jComboExt = new JComboBox<String>(new String[]{".epub", ".kepub.epub", ".fxl.kepub.epub", ".mobi", ".mobi+.epub"});
jComboExt.setToolTipText("出力するファイルの拡張子を選択します。 mobi出力時はKindlegenが必要になります");
jComboExt.setEditable(true);
jComboExt.setMaximumSize(new Dimension(110, 24));
jComboExt.setPreferredSize(new Dimension(110, 24));
panel.add(jComboExt);
label = new JLabel(" ");
panel.add(label);
//出力ファイル名設定
jCheckAutoFileName = new JCheckBox("出力ファイル名に表題利用", true);
jCheckAutoFileName.setFocusPainted(false);
panel.add(jCheckAutoFileName);
label = new JLabel(" ");
panel.add(label);
//ファイルの上書き許可
jCheckOverWrite = new JCheckBox("出力ファイル上書き", true);
jCheckOverWrite.setFocusPainted(false);
panel.add(jCheckOverWrite);
////////////////////////////////
//出力先 履歴をpropsから読み込んで設定
////////////////////////////////
dstPathChooser = new DstPathChooserListener(this);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setMinimumSize(panelSize);
panel.setMaximumSize(panelSize);
panel.setPreferredSize(panelSize);
panel.setBorder(padding4H2V);
tabPanel.add(panel);
//出力先
label = new JLabel("出力先: ");
panel.add(label);
jCheckSamePath = new JCheckBox("入力と同じ", true);
jCheckSamePath.setToolTipText("入力ファイルと同じ場所に出力します");
panel.add(jCheckSamePath);
jCheckSamePath.addChangeListener(e -> {
jComboDstPath.setEditable(!jCheckSamePath.isSelected());
jComboDstPath.setForeground(jCheckSamePath.isSelected()?Color.gray:Color.black);
jComboDstPath.repaint();
});
jComboDstPath = new JComboBox<String>();
jComboDstPath.setToolTipText("出力先を指定します。変換時に履歴に追加されます。フォルダのドロップでも設定できます");
jComboDstPath.setEditable(false);
jComboDstPath.setForeground(Color.gray);
jComboDstPath.setPreferredSize(new Dimension(260, 24));
//パスを追加
//vecDstPath.add("[入力ファイルと同じ場所]");
String propValue = props.getProperty("DstPathList");
String dstPath = props.getProperty("DstPath");
if (propValue!=null && !propValue.isEmpty()) {
for (String listPath : propValue.split(",")) {
if (!"".equals(listPath)) jComboDstPath.addItem(listPath);
}
}
if (dstPath!=null && !dstPath.isEmpty()) {
jComboDstPath.setSelectedItem(dstPath);
}
panel.add(jComboDstPath);
new DropTarget(jComboDstPath.getEditor().getEditorComponent(), DnDConstants.ACTION_COPY_OR_MOVE, new DropDstPathListener(), true);
//選択解除
if ("".equals(props.getProperty("SamePath"))) jCheckSamePath.setSelected(false);
jButtonDstPath = new JButton("選択");
jButtonDstPath.setBorder(padding3);
jButtonDstPath.setIcon(new ImageIcon(Objects.requireNonNull(AozoraEpub3Applet.class.getResource("images/dst_path.png"))));
jButtonDstPath.setFocusPainted(false);
jButtonDstPath.addActionListener(dstPathChooser);
panel.add(jButtonDstPath);
////////////////////////////////
/*group = new ButtonGroup();
jRadioRtL = new JRadioButton("右→左");
jRadioRtL.setFocusPainted(false);
panel.add(jRadioRtL);
group.add(jRadioRtL);
jRadioLtR = new JRadioButton("左→右");
jRadioLtR.setFocusPainted(false);
panel.add(jRadioLtR);
group.add(jRadioLtR);*/
////////////////////////////////
//変換
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setMaximumSize(new Dimension(1920, 32));
panel.setPreferredSize(new Dimension(1920, 32));
panel.setBorder(padding4H);
tabPanel.add(panel);
//左パネル
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
//panel1.setPreferredSize(panelSize);
panel1.setBorder(padding0);
//入力文字コード
label = new JLabel("入力文字コード");
label.setBorder(padding0);
panel1.add(label);
jComboEncType = new JComboBox<String>(new String[]{"AUTO","MS932", "UTF-8"});
jComboEncType.setToolTipText("入力ファイルのテキストファイルの文字コード。青空文庫の標準はMS932(SJIS)です");
jComboEncType.setFocusable(false);
jComboEncType.setPreferredSize(new Dimension(70, 22));
panel1.add(jComboEncType);
label = new JLabel("言語");
label.setBorder(padding0);
panel1.add(label);
jComboLangType = new JComboBox<String>(new String[]{"ja", "en"});
jComboLangType.setToolTipText("出力するEPUBの言語を選択する。");
jComboLangType.setEditable(true);
//jComboLangType.setFocusable(false);
jComboLangType.setPreferredSize(new Dimension(70, 22));
panel1.add(jComboLangType);
panel.add(panel1);
//右パネル
JPanel panel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
//panel2.setPreferredSize(panelSize);
panel.setBorder(padding0);
//縦書き横書き
buttonGroup = new ButtonGroup();
jRadioVertical = new JRadioButton();
jRadioVertical.setSelected(true);
jRadioVertical.setFocusPainted(false);
//jRadioVertical.setBorder(BorderFactory.createEmptyBorder(0, 100, 0, 0));
jRadioVertical.setBorder(padding0);
jRadioVertical.setIconTextGap(0);
label = new JLabel("縦書き", new ImageIcon(Objects.requireNonNull(AozoraEpub3Applet.class.getResource("images/page_vertical.png"))), JLabel.LEFT);
label.setBorder(iconPadding);
jRadioVertical.add(label);
panel2.add(jRadioVertical);
buttonGroup.add(jRadioVertical);
jRadioHorizontal = new JRadioButton();
jRadioHorizontal.setFocusPainted(false);
jRadioHorizontal.setBorder(padding0);
jRadioHorizontal.setIconTextGap(0);
label = new JLabel("横書き ", new ImageIcon(Objects.requireNonNull(AozoraEpub3Applet.class.getResource("images/page_horizontal.png"))), JLabel.LEFT);
label.setBorder(iconPadding);
jRadioHorizontal.add(label);
panel2.add(jRadioHorizontal);
buttonGroup.add(jRadioHorizontal);
//ファイル選択
jButtonFile = new JButton("ファイル選択");
jButtonFile.setToolTipText("ファイル選択後に変換処理を開始します");
jButtonFile.setBorder(padding5H3V);
//jButtonFile.setPreferredSize(new Dimension(100, 24));
jButtonFile.setIcon(new ImageIcon(Objects.requireNonNull(AozoraEpub3Applet.class.getResource("images/convert.png"))));
jButtonFile.setFocusPainted(false);
jButtonFile.addActionListener(new FileChooserListener(this));
panel2.add(jButtonFile);
panel.add(panel2);
ChatGPT:
このSwingのUIコードをAndroidのPreferenceScreenに書き換えるには、PreferenceFragmentCompatを使用してXMLベースで構成するのが基本的な方法です。以下に、可能な限り近いAndroid PreferenceScreen 表現をXMLで示し、その後、必要に応じて PreferenceFragmentCompat クラスでの処理を記述します。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 出力ファイル設定 --> <PreferenceCategory android:title="出力ファイル設定"> <ListPreference android:key="file_extension" android:title="拡張子" android:summary="出力するファイルの拡張子" android:entries=".epub,.kepub.epub,.fxl.kepub.epub,.mobi,.mobi+.epub" android:entryValues=".epub,.kepub.epub,.fxl.kepub.epub,.mobi,.mobi+.epub" android:defaultValue=".epub" /> <SwitchPreferenceCompat android:key="use_title_for_filename" android:title="出力ファイル名に表題利用" android:defaultValue="true" /> <SwitchPreferenceCompat android:key="overwrite_output" android:title="出力ファイル上書き" android:defaultValue="true" /> </PreferenceCategory> <!-- 出力先 --> <PreferenceCategory android:title="出力先"> <SwitchPreferenceCompat android:key="same_path" android:title="入力と同じ場所に出力" android:defaultValue="true" /> <EditTextPreference android:key="output_path" android:title="出力先フォルダ" android:summary="出力先を指定します" android:dialogTitle="フォルダパスを入力" android:enabled="false" /> </PreferenceCategory> <!-- 変換 --> <PreferenceCategory android:title="変換設定"> <ListPreference android:key="input_encoding" android:title="入力文字コード" android:entries="AUTO,MS932,UTF-8" android:entryValues="AUTO,MS932,UTF-8" android:defaultValue="AUTO" /> <ListPreference android:key="language" android:title="言語" android:entries="日本語, 英語" android:entryValues="ja,en" android:defaultValue="ja" /> <ListPreference android:key="text_direction" android:title="レイアウト方向" android:entries="縦書き, 横書き" android:entryValues="vertical,horizontal" android:defaultValue="vertical" /> <Preference android:key="select_file" android:title="ファイル選択" android:summary="ファイルを選択して変換を開始" /> </PreferenceCategory> </PreferenceScreen>
class OutputSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences_output, rootKey) val samePathPref = findPreference<SwitchPreferenceCompat>("same_path") val outputPathPref = findPreference<EditTextPreference>("output_path") samePathPref?.setOnPreferenceChangeListener { _, newValue -> val enabled = !(newValue as Boolean) outputPathPref?.isEnabled = enabled true } val fileSelect = findPreference<Preference>("select_file") fileSelect?.setOnPreferenceClickListener { // ファイル選択ダイアログ処理をここに true } } }
- DropTarget のようなドラッグ&ドロップ機能は PreferenceScreen ではサポートされていないため、別途 UI を用意して Activity / Fragment 側で実装します。
- 「アイコン付きラジオボタン」なども Preference では制限があるため、カスタム UI が必要になることがあります。
DropTarget のようなドラッグ&ドロップ機能は PreferenceScreen ではサポートされていないため、別途 UI を用意して Activity / Fragment 側で実装します。
「アイコン付きラジオボタン」なども Preference では制限があるため、カスタム UI が必要になることがあります。
この形式で問題ないですか? それとも、Preferenceではなく通常のFragmentやActivityでレイアウトを作る方が希望ですか?
あなた:
ドラッグ&ドロップ機能ha
ChatGPT:
了解です、「ドラッグ&ドロップ機能は?」ですね! Androidでファイルやフォルダのドラッグ&ドロップ機能を実装する場合、PreferenceScreenのようなシンプルな設定UIでは基本的に 非対応 です。ただし、通常のFragmentやActivityのカスタムビューを使えば、ドラッグ&ドロップ機能を実現できます。
通常のView(たとえばEditText, TextView, LinearLayoutなど)に以下のようなリスナーを設定して実現します:
val dropTarget = findViewById<EditText>(R.id.editTextPath) dropTarget.setOnDragListener { v, event -> when (event.action) { DragEvent.ACTION_DRAG_STARTED -> { true } DragEvent.ACTION_DROP -> { val item: ClipData.Item = event.clipData.getItemAt(0) val path = item.uri.path // ここでパス取得 dropTarget.setText(path) true } else -> false } }
PreferenceScreenではなく、FragmentやActivityの中で以下のようなUIを作って実現します:
<!-- res/layout/fragment_output_settings.xml --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/editTextPath" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="ここにフォルダをドロップ" android:focusable="false" android:background="@drawable/edit_text_border" /> </LinearLayout>
Androidではユーザーがファイルマネージャーなどから直接ドラッグしてくるケースは少ないです。 そのため通常は以下の方法を組み合わせます:
- フォルダ選択ダイアログ(Storage Access Framework)
- 「共有」メニューから受け取る
- 端末内でのドラッグ&ドロップ(同アプリ内のリストビュー間など)
フォルダ選択ダイアログ(Storage Access Framework)
「共有」メニューから受け取る
端末内でのドラッグ&ドロップ(同アプリ内のリストビュー間など)
操作 | Androidでの一般的な対応方法 |
---|---|
ドラッグしてパスを設定 | フォルダ選択ダイアログ or SAFを使う |
ドラッグしてファイルを読み込み | Intent.ACTION_GET_CONTENTを使う |
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) startActivityForResult(intent, REQUEST_CODE_PICK_FOLDER)
その後、選ばれたフォルダのURIを保存・使用できます。
- PreferenceScreenはドラッグ&ドロップに不向き。
- 通常のFragment + EditText + setOnDragListenerで実装可能。
- 外部からのドラッグは限定的なので、代替としてフォルダ選択ダイアログを使うのが一般的。
PreferenceScreenはドラッグ&ドロップに不向き。
通常のFragment + EditText + setOnDragListenerで実装可能。
外部からのドラッグは限定的なので、代替としてフォルダ選択ダイアログを使うのが一般的。
ドラッグ&ドロップ機能を実装したいのは「出力先パス」だけですか? それとも他にもファイル選択や設定項目がありますか?どこまでをドラッグ対応にしたいか教えてもらえたら、よりピッタリなコードにできます!
あなた:
下記のコードをAndroidのpreferenceに書き換えて
////////////////////////////////////////////////////////////////
//Tab 画像配置
////////////////////////////////////////////////////////////////
tabPanel = new JPanel();
//tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.Y_AXIS));
tabPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 0));
jTabbedPane.addTab("画像1", imageIcon, tabPanel);
////////////////////////////////
//挿絵なし
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("画像注記"));
tabPanel.add(panel);
jCheckNoIllust = new JCheckBox("挿絵除外 ");
jCheckNoIllust.setFocusPainted(false);
jCheckNoIllust.setToolTipText("テキストの画像注記は表紙と外字画像以外はePubに格納されません");
jCheckNoIllust.setBorder(padding2);
panel.add(jCheckNoIllust);
////////////////////////////////
//画面サイズ
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("画面・表紙サイズ"));
tabPanel.add(panel);
//画面サイズ
label = new JLabel(" 画面: 横");
panel.add(label);
jTextDispW = new JTextField("1600");
jTextDispW.setHorizontalAlignment(JTextField.RIGHT);
jTextDispW.setMaximumSize(text4);
jTextDispW.setPreferredSize(text4);
jTextDispW.addFocusListener(new TextSelectFocusListener(jTextDispW));
jTextDispW.setInputVerifier(new IntegerInputVerifier(600, 1, 9999));
panel.add(jTextDispW);
label = new JLabel("x");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel("縦");
panel.add(label);
jTextDispH = new JTextField("2560");
jTextDispH.setHorizontalAlignment(JTextField.RIGHT);
jTextDispH.setMaximumSize(text4);
jTextDispH.setPreferredSize(text4);
jTextDispH.addFocusListener(new TextSelectFocusListener(jTextDispH));
jTextDispH.setInputVerifier(new IntegerInputVerifier(800, 1, 9999));
panel.add(jTextDispH);
label = new JLabel("px");
label.setBorder(padding2H);
panel.add(label);
////////////////////////////////
//表紙サイズ
//横x縦
label = new JLabel(" 表紙: 横");
panel.add(label);
jTextCoverW = new JTextField("0");
jTextCoverW.setHorizontalAlignment(JTextField.RIGHT);
jTextCoverW.setInputVerifier(new IntegerInputVerifier(600, 0, 4096));
jTextCoverW.setMaximumSize(text4);
jTextCoverW.setPreferredSize(text4);
jTextCoverW.addFocusListener(new TextSelectFocusListener(jTextCoverW));
panel.add(jTextCoverW);
label = new JLabel("x");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel("縦");
panel.add(label);
jTextCoverH = new JTextField("0");
jTextCoverH.setHorizontalAlignment(JTextField.RIGHT);
jTextCoverH.setInputVerifier(new IntegerInputVerifier(800, 0, 4096));
jTextCoverH.setMaximumSize(text4);
jTextCoverH.setPreferredSize(text4);
jTextCoverH.addFocusListener(new TextSelectFocusListener(jTextCoverH));
panel.add(jTextCoverH);
label = new JLabel("px");
label.setBorder(padding2H);
panel.add(label);
////////////////////////////////
//画像倍率
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("画像表示倍率"));
tabPanel.add(panel);
jCheckImageScale = new JCheckBox("有効 ", true);
jCheckImageScale.setToolTipText("画面の解像度に合わせて画像の幅を%指定します。画像キャプションがはみ出る場合も指定してください");
jCheckImageScale.setFocusPainted(false);
jCheckImageScale.setBorder(padding2);
jCheckImageScale.addChangeListener(e -> jTextImageScale.setEditable(jCheckImageScale.isSelected()));
panel.add(jCheckImageScale);
jTextImageScale = new JTextField("1.0");
jTextImageScale.setToolTipText("指定倍率で画像を拡大表示します。64px以下の画像は変更されません");
jTextImageScale.setHorizontalAlignment(JTextField.RIGHT);
jTextImageScale.setInputVerifier(new FloatInputVerifier(1, 0.01f, 30));
jTextImageScale.setMaximumSize(text4);
jTextImageScale.setPreferredSize(text4);
jTextImageScale.addFocusListener(new TextSelectFocusListener(jTextImageScale));
panel.add(jTextImageScale);
label = new JLabel("倍");
panel.add(label);
ChatGPT:
AndroidのPreferenceScreenにSwingの「画像配置」タブ(挿絵除外、画面サイズ、表紙サイズ、画像表示倍率)を置き換えるには、PreferenceFragmentCompatまたはPreferenceScreen XMLを使って構築するのが一般的です。
以下にそのコードの変換例を紹介します。UIの見た目はSwingと異なりますが、設定値の保存・取得が容易で、ユーザーにとっても馴染みある形式になります。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 挿絵除外 --> <CheckBoxPreference android:key="exclude_illustrations" android:title="挿絵除外" android:summary="テキストの画像注記は表紙と外字画像以外はePubに格納されません" android:defaultValue="false" /> <!-- 画面サイズ --> <PreferenceCategory android:title="画面・表紙サイズ"> <EditTextPreference android:key="screen_width" android:title="画面 横(px)" android:inputType="number" android:defaultValue="1600" /> <EditTextPreference android:key="screen_height" android:title="画面 縦(px)" android:inputType="number" android:defaultValue="2560" /> <EditTextPreference android:key="cover_width" android:title="表紙 横(px)" android:inputType="number" android:defaultValue="0" /> <EditTextPreference android:key="cover_height" android:title="表紙 縦(px)" android:inputType="number" android:defaultValue="0" /> </PreferenceCategory> <!-- 画像倍率 --> <PreferenceCategory android:title="画像表示倍率"> <CheckBoxPreference android:key="image_scale_enabled" android:title="有効" android:summary="画面の解像度に合わせて画像の幅を%指定します" android:defaultValue="true" /> <EditTextPreference android:key="image_scale_factor" android:title="画像表示倍率(倍)" android:inputType="numberDecimal" android:defaultValue="1.0" /> </PreferenceCategory> </PreferenceScreen>
class ImageSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences_image, rootKey) val imageScalePref = findPreference<EditTextPreference>("image_scale_factor") val scaleEnabled = findPreference<CheckBoxPreference>("image_scale_enabled") scaleEnabled?.setOnPreferenceChangeListener { _, newValue -> imageScalePref?.isEnabled = newValue as Boolean true } imageScalePref?.isEnabled = scaleEnabled?.isChecked == true } }
- EditTextPreferenceはバリデーションを手動で入れる必要があります(例えば数値範囲チェック)。
- CheckBoxPreferenceで連動制御(有効/無効)したい場合はKotlinやJavaで設定する必要があります。
- 表示倍率やサイズの制限(最大値・最小値など)を厳密に扱うなら、DialogPreferenceをカスタム実装する方法もあります。
EditTextPreferenceはバリデーションを手動で入れる必要があります(例えば数値範囲チェック)。
CheckBoxPreferenceで連動制御(有効/無効)したい場合はKotlinやJavaで設定する必要があります。
表示倍率やサイズの制限(最大値・最小値など)を厳密に扱うなら、DialogPreferenceをカスタム実装する方法もあります。
必要であれば、この設定に対応する SharedPreferences の読み書きコードや、バリデーション付きのカスタム DialogPreference の実装も用意できます。やってみますか?
あなた:
下記のコードをAndroidのpreferenceに書き換えて
////////////////////////////////
//画像回り込み
////////////////////////////////
//画像回り込み
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("画像回り込み (※単ページ化より優先)"));
tabPanel.add(panel);
jCheckImageFloat = new JCheckBox("回り込み有効 ");
jCheckImageFloat.setToolTipText("画像の実サイズが指定サイズ以下の画像を回り込み設定します");
jCheckImageFloat.setFocusPainted(false);
jCheckImageFloat.setBorder(padding2);
jCheckImageFloat.addChangeListener(e -> { jTextImageFloatW.setEditable(jCheckImageFloat.isSelected()); jTextImageFloatH.setEditable(jCheckImageFloat.isSelected());});
panel.add(jCheckImageFloat);
label = new JLabel("横");
panel.add(label);
jTextImageFloatW = new JTextField("600");
jTextImageFloatW.setHorizontalAlignment(JTextField.RIGHT);
jTextImageFloatW.setInputVerifier(new IntegerInputVerifier(600, 1, 9999));
jTextImageFloatW.setMaximumSize(text4);
jTextImageFloatW.setPreferredSize(text4);
jTextImageFloatW.addFocusListener(new TextSelectFocusListener(jTextImageFloatW));
jTextImageFloatW.setEditable(jCheckImageFloat.isSelected());
panel.add(jTextImageFloatW);
label = new JLabel("x");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel("縦");
panel.add(label);
jTextImageFloatH = new JTextField("400");
jTextImageFloatH.setHorizontalAlignment(JTextField.RIGHT);
jTextImageFloatH.setInputVerifier(new IntegerInputVerifier(400, 1, 9999));
jTextImageFloatH.setMaximumSize(text4);
jTextImageFloatH.setPreferredSize(text4);
jTextImageFloatH.addFocusListener(new TextSelectFocusListener(jTextImageFloatH));
jTextImageFloatH.setEditable(jCheckImageFloat.isSelected());
panel.add(jTextImageFloatH);
label = new JLabel("px以下");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel(" 配置");
panel.add(label);
jComboImageFloatType = new JComboBox<String>(new String[]{"上/左","下/右"});
jComboImageFloatType.setFocusable(false);
jComboImageFloatType.setBorder(padding0);
jComboImageFloatType.setPreferredSize(new Dimension(text4.width+24, 20));
panel.add(jComboImageFloatType);
////////////////////////////////
//画像単ページ化
////////////////////////////////
panelV = new JPanel();
panelV.setLayout(new BoxLayout(panelV, BoxLayout.Y_AXIS));
panelV.setBorder(new NarrowTitledBorder("画像単ページ化"));
tabPanel.add(panelV);
//上段
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setMaximumSize(panelVMaxSize);
panel.setBorder(padding4B);
panelV.add(panel);
//横x縦
label = new JLabel("横");
panel.add(label);
jTextSinglePageSizeW = new JTextField("200");
jTextSinglePageSizeW.setHorizontalAlignment(JTextField.RIGHT);
jTextSinglePageSizeW.setInputVerifier(new IntegerInputVerifier(400, 1, 9999));
jTextSinglePageSizeW.setMaximumSize(text4);
jTextSinglePageSizeW.setPreferredSize(text4);
jTextSinglePageSizeW.addFocusListener(new TextSelectFocusListener(jTextSinglePageSizeW));
panel.add(jTextSinglePageSizeW);
label = new JLabel("x");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel("縦");
panel.add(label);
jTextSinglePageSizeH = new JTextField("300");
jTextSinglePageSizeH.setHorizontalAlignment(JTextField.RIGHT);
jTextSinglePageSizeH.setInputVerifier(new IntegerInputVerifier(600, 1, 9999));
jTextSinglePageSizeH.setMaximumSize(text4);
jTextSinglePageSizeH.setPreferredSize(text4);
jTextSinglePageSizeH.addFocusListener(new TextSelectFocusListener(jTextSinglePageSizeH));
panel.add(jTextSinglePageSizeH);
label = new JLabel("px以上 ");
label.setBorder(padding2H);
panel.add(label);
//横のみ
label = new JLabel("横のみ");
label.setBorder(padding2H);
panel.add(label);
jTextSinglePageWidth = new JTextField("300");
jTextSinglePageWidth.setHorizontalAlignment(JTextField.RIGHT);
jTextSinglePageWidth.setInputVerifier(new IntegerInputVerifier(600, 1, 9999));
jTextSinglePageWidth.setMaximumSize(text4);
jTextSinglePageWidth.setPreferredSize(text4);
jTextSinglePageWidth.addFocusListener(new TextSelectFocusListener(jTextSinglePageWidth));
panel.add(jTextSinglePageWidth);
label = new JLabel("px以上");
label.setBorder(padding2H);
panel.add(label);
//下段
panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panelV.add(panel);
label = new JLabel("縮小表示 (");
label.setBorder(padding2H);
panel.add(label);
buttonGroup = new ButtonGroup();
jRadioImageSizeType1 = new JRadioButton("指定無し");
jRadioImageSizeType1.setToolTipText("画像のサイズを指定しません。 端末が自動で縮小します(Kindle, Kobo)");
jRadioImageSizeType1.setFocusPainted(false);
jRadioImageSizeType1.setBorder(padding2);
jRadioImageSizeType1.setIconTextGap(1);
panel.add(jRadioImageSizeType1);
buttonGroup.add(jRadioImageSizeType1);
/*jRadioImageSizeType2 = new JRadioButton("高さ%", true);
jRadioImageSizeType2.setToolTipText("画面の縦横比に合せて画像の高さのみ%指定します。画面設定より縦長の端末でははみ出すか縦長に表示されます");
jRadioImageSizeType2.setFocusPainted(false);
jRadioImageSizeType2.setBorder(padding2);
jRadioImageSizeType2.setIconTextGap(1);
panel.add(jRadioImageSizeType2);
buttonGroup.add(jRadioImageSizeType2);*/
jRadioImageSizeType3 = new JRadioButton("縦横比");
jRadioImageSizeType3.setToolTipText("画面の縦横比に合せて幅または高さを100%指定します。画面回転で画像がはみ出す場合があります");
jRadioImageSizeType3.setFocusPainted(false);
jRadioImageSizeType3.setBorder(padding2);
jRadioImageSizeType3.setIconTextGap(1);
panel.add(jRadioImageSizeType3);
buttonGroup.add(jRadioImageSizeType3);
label = new JLabel(") ");
label.setBorder(padding2H);
panel.add(label);
jCheckFitImage = new JCheckBox("拡大表示", true);
jCheckFitImage.setToolTipText("画面サイズより小さい画像を幅高さに合わせて拡大表示します。画面回転で画像がはみ出す場合があります");
jCheckFitImage.setFocusPainted(false);
jCheckFitImage.setBorder(padding2);
panel.add(jCheckFitImage);
buttonGroup = new ButtonGroup();
ChatGPT:
以下は、指定されたSwing UIの「画像回り込み」と「画像単ページ化」に関する設定を、AndroidのPreferenceScreen形式に書き換えた例です。PreferenceFragmentCompatで実装することを想定しています。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 画像回り込み --> <PreferenceCategory android:title="画像回り込み (※単ページ化より優先)"> <SwitchPreferenceCompat android:key="image_float_enabled" android:title="回り込み有効" android:summary="画像の実サイズが指定サイズ以下の画像を回り込み設定します" android:defaultValue="false" /> <EditTextPreference android:key="image_float_width" android:title="横 (px)" android:dialogTitle="画像回り込み 横サイズ" android:inputType="number" android:defaultValue="600" /> <EditTextPreference android:key="image_float_height" android:title="縦 (px)" android:dialogTitle="画像回り込み 縦サイズ" android:inputType="number" android:defaultValue="400" /> <ListPreference android:key="image_float_position" android:title="配置" android:defaultValue="上/左" android:entries="@array/image_float_position_entries" android:entryValues="@array/image_float_position_values" /> </PreferenceCategory> <!-- 画像単ページ化 --> <PreferenceCategory android:title="画像単ページ化"> <EditTextPreference android:key="single_page_width" android:title="単ページ 横 (px)" android:inputType="number" android:defaultValue="200" /> <EditTextPreference android:key="single_page_height" android:title="単ページ 縦 (px)" android:inputType="number" android:defaultValue="300" /> <EditTextPreference android:key="single_page_width_only" android:title="横のみ (px)" android:inputType="number" android:defaultValue="300" /> <ListPreference android:key="image_size_mode" android:title="縮小表示モード" android:defaultValue="none" android:entries="@array/image_size_mode_entries" android:entryValues="@array/image_size_mode_values" /> <SwitchPreferenceCompat android:key="fit_image" android:title="拡大表示" android:summary="画面サイズより小さい画像を幅高さに合わせて拡大表示します" android:defaultValue="true" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="image_float_position_entries"> <item>上/左</item> <item>下/右</item> </string-array> <string-array name="image_float_position_values"> <item>top_left</item> <item>bottom_right</item> </string-array> <string-array name="image_size_mode_entries"> <item>指定無し</item> <item>縦横比</item> </string-array> <string-array name="image_size_mode_values"> <item>none</item> <item>aspect_ratio</item> </string-array> </resources>
class ImagePreferenceFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.image_preferences, rootKey) } }
必要であれば、数値範囲(例: 1〜9999)や動的なEditable制御(SwitchとEditTextの連動)もPreference.OnPreferenceChangeListenerを使って対応可能です。実装例が必要であれば追加します!
どうします?次はその辺のロジックも書きますか?
あなた:
下記のコードをAndroidのpreferenceに書き換えて
//Float表示
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("Float指定 (Readerのみ)"));
tabPanel.add(panel);
jCheckImageFloatPage = new JCheckBox("単ページ画像");
jCheckImageFloatPage.setToolTipText("単ページ対象の画像をfloat表示します。 xhtmlは分割されません");
jCheckImageFloatPage.setFocusPainted(false);
jCheckImageFloatPage.setBorder(padding2);
panel.add(jCheckImageFloatPage);
jCheckImageFloatBlock = new JCheckBox("通常画像");
jCheckImageFloatBlock.setToolTipText("回り込み、単ページ以外の画像をfloat表示します。 64px以上の画像のみ");
jCheckImageFloatBlock.setFocusPainted(false);
jCheckImageFloatBlock.setBorder(padding2);
panel.add(jCheckImageFloatBlock);
////////////////////////////////////////////////////////////////
//Tab 画像2
////////////////////////////////////////////////////////////////
tabPanel = new JPanel();
//tabPanel.setLayout(new BoxLayout(tabPanel, BoxLayout.Y_AXIS));
tabPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 0));
jTabbedPane.addTab("画像2", imageIcon, tabPanel);
////////////////////////////////
//全画面+SVG
////////////////////////////////
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("全画面表示"));
tabPanel.add(panel);
jCheckSvgImage = new JCheckBox("SVGタグ出力(画像zipのみ) ");
jCheckSvgImage.setFocusPainted(false);
jCheckSvgImage.setToolTipText("画像のみのzipの場合、固定レイアウト+SVGタグで出力します");
jCheckSvgImage.setBorder(padding2);
panel.add(jCheckSvgImage);
////////////////////////////////
//画像調整
////////////////////////////////
//Jpeg圧縮率
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("Jpeg圧縮率"));
tabPanel.add(panel);
jTextJpegQuality = new JTextField("85");
jTextJpegQuality.setToolTipText("表紙編集、縮小、回転、余白除去時のJpeg保存時の画質(100が最高画質)");
jTextJpegQuality.setHorizontalAlignment(JTextField.RIGHT);
jTextJpegQuality.setInputVerifier(new IntegerInputVerifier(85, 30, 100));
jTextJpegQuality.setMaximumSize(text3);
jTextJpegQuality.setPreferredSize(text3);
jTextJpegQuality.addFocusListener(new TextSelectFocusListener(jTextJpegQuality));
panel.add(jTextJpegQuality);
panel.add(new JLabel(" (30~100)"));
////////////////////////////////
//ガンマ補正
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("色調整"));
tabPanel.add(panel);
jCheckGamma = new JCheckBox("ガンマ補正");
jCheckGamma.setToolTipText("画像の濃さを変更します (濃:0.2~1.8:淡)");
jCheckGamma.setFocusPainted(false);
jCheckGamma.setBorder(padding2);
jCheckGamma.setIconTextGap(2);
jCheckGamma.addChangeListener(e -> jTextGammaValue.setEditable(jCheckGamma.isSelected()));
panel.add(jCheckGamma);
jTextGammaValue = new JTextField("1.0");
jTextGammaValue.setToolTipText(jCheckGamma.getToolTipText());
jTextGammaValue.setHorizontalAlignment(JTextField.RIGHT);
jTextGammaValue.setInputVerifier(new FloatInputVerifier(1.0f, 0.2f, 1.8f));
jTextGammaValue.setMaximumSize(text3);
jTextGammaValue.setPreferredSize(text3);
jTextGammaValue.setEditable(jCheckGamma.isSelected());
jTextGammaValue.addFocusListener(new TextSelectFocusListener(jTextGammaValue));
panel.add(jTextGammaValue);
////////////////////////////////
//画像縮小
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(new NarrowTitledBorder("画像縮小回転"));
tabPanel.add(panel);
ChangeListener resizeChangeLister = e -> setResizeTextEditable(true);
//横
jCheckResizeW = new JCheckBox("横");
jCheckResizeW.setFocusPainted(false);
jCheckResizeW.setBorder(padding2);
jCheckResizeW.setIconTextGap(2);
jCheckResizeW.addChangeListener(resizeChangeLister);
panel.add(jCheckResizeW);
jTextResizeNumW = new JTextField("2048");
jTextResizeNumW.setHorizontalAlignment(JTextField.RIGHT);
jTextResizeNumW.setInputVerifier(new IntegerInputVerifier(2048, 100, 9999));
jTextResizeNumW.setMaximumSize(text4);
jTextResizeNumW.setPreferredSize(text4);
jTextResizeNumW.addFocusListener(new TextSelectFocusListener(jTextResizeNumW));
jTextResizeNumW.setEditable(jCheckResizeW.isSelected());
panel.add(jTextResizeNumW);
label = new JLabel("px以下 ");
label.setBorder(padding2H);
panel.add(label);
//縦
jCheckResizeH = new JCheckBox("縦");
jCheckResizeH.setFocusPainted(false);
jCheckResizeH.setBorder(padding2);
jCheckResizeH.setIconTextGap(2);
jCheckResizeH.addChangeListener(resizeChangeLister);
panel.add(jCheckResizeH);
jTextResizeNumH = new JTextField("2048");
jTextResizeNumH.setHorizontalAlignment(JTextField.RIGHT);
jTextResizeNumH.setInputVerifier(new IntegerInputVerifier(2048, 100, 9999));
jTextResizeNumH.setMaximumSize(text4);
jTextResizeNumH.setPreferredSize(text4);
jTextResizeNumH.addFocusListener(new TextSelectFocusListener(jTextResizeNumH));
panel.add(jTextResizeNumH);
label = new JLabel("px以下");
label.setBorder(padding2H);
panel.add(label);
this.setResizeTextEditable(true);
//自動画像回転
label = new JLabel(" 自動回転");
label.setBorder(padding2H);
panel.add(label);
jComboRotateImage = new JComboBox<String>(new String[]{"なし","右","左"});
jComboRotateImage.setToolTipText("単ページ時画面の縦横比に合わせて画像を回転します");
jComboRotateImage.setFocusable(false);
jComboRotateImage.setBorder(padding0);
jComboRotateImage.setPreferredSize(new Dimension(text4.width+24, 20));
panel.add(jComboRotateImage);
ChatGPT:
以下に、提示されたSwingコードをAndroidのPreferenceScreen形式に変換したサンプルを記載します。これはres/xml/preferences.xmlで定義し、PreferenceFragmentCompatから読み込む形を想定しています。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Float指定 --> <PreferenceCategory android:title="Float指定 (Readerのみ)"> <CheckBoxPreference android:key="float_image_single_page" android:title="単ページ画像" android:summary="単ページ対象の画像をfloat表示します。xhtmlは分割されません" /> <CheckBoxPreference android:key="float_image_block" android:title="通常画像" android:summary="回り込み、単ページ以外の画像をfloat表示します。64px以上の画像のみ" /> </PreferenceCategory> <!-- 全画面表示 --> <PreferenceCategory android:title="全画面表示"> <CheckBoxPreference android:key="output_svg" android:title="SVGタグ出力(画像zipのみ)" android:summary="画像のみのzipの場合、固定レイアウト+SVGタグで出力します" /> </PreferenceCategory> <!-- Jpeg圧縮率 --> <PreferenceCategory android:title="Jpeg圧縮率"> <EditTextPreference android:key="jpeg_quality" android:title="圧縮率 (30~100)" android:summary="表紙編集、縮小、回転、余白除去時のJpeg保存時の画質(100が最高画質)" android:inputType="number" /> </PreferenceCategory> <!-- 色調整 --> <PreferenceCategory android:title="色調整"> <CheckBoxPreference android:key="gamma_correction" android:title="ガンマ補正" android:summary="画像の濃さを変更します (濃:0.2~1.8:淡)" /> <EditTextPreference android:key="gamma_value" android:title="ガンマ値" android:summary="例: 1.0" android:inputType="numberDecimal" /> </PreferenceCategory> <!-- 画像縮小回転 --> <PreferenceCategory android:title="画像縮小回転"> <!-- 横縮小 --> <CheckBoxPreference android:key="resize_width_enabled" android:title="横: 有効化" /> <EditTextPreference android:key="resize_width" android:title="横(px以下)" android:inputType="number" /> <!-- 縦縮小 --> <CheckBoxPreference android:key="resize_height_enabled" android:title="縦: 有効化" /> <EditTextPreference android:key="resize_height" android:title="縦(px以下)" android:inputType="number" /> <!-- 自動回転 --> <ListPreference android:key="auto_rotate_image" android:title="自動回転" android:summary="単ページ時画面の縦横比に合わせて画像を回転します" android:entries="@array/rotate_options" android:entryValues="@array/rotate_values" android:defaultValue="none" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="rotate_options"> <item>なし</item> <item>右</item> <item>左</item> </string-array> <string-array name="rotate_values"> <item>none</item> <item>right</item> <item>left</item> </string-array> </resources>
public class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.preferences, rootKey); // 例: gamma_correction によって gamma_value を有効/無効化 CheckBoxPreference gammaCheck = findPreference("gamma_correction"); EditTextPreference gammaValue = findPreference("gamma_value"); if (gammaCheck != null && gammaValue != null) { gammaValue.setEnabled(gammaCheck.isChecked()); gammaCheck.setOnPreferenceChangeListener((preference, newValue) -> { gammaValue.setEnabled((Boolean) newValue); return true; }); } } }
必要であれば、設定画面のレイアウトカスタム(カテゴリのアイコン表示や分割表示など)もできます。
次に他のパート(画像回り込みや単ページ化)も続けて変換していきますか?
あなた:
下記のコードをAndroidのpreferenceに書き換えて
////////////////////////////////
//余白除去
////////////////////////////////
panelV = new JPanel();
panelV.setLayout(new BoxLayout(panelV, BoxLayout.Y_AXIS));
panelV.setBorder(new NarrowTitledBorder("余白除去"));
tabPanel.add(panelV);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(padding4B);
panelV.add(panel);
jCheckAutoMargin = new JCheckBox("有効 ");
jCheckAutoMargin.setFocusPainted(false);
jCheckAutoMargin.setBorder(padding2);
jCheckAutoMargin.setIconTextGap(2);
jCheckAutoMargin.addChangeListener(e -> {
boolean selected = jCheckAutoMargin.isSelected();
jTextAutoMarginLimitH.setEditable(selected);
jTextAutoMarginLimitV.setEditable(selected);
jTextAutoMarginWhiteLevel.setEditable(selected);
jTextAutoMarginPadding.setEditable(selected);
jTextAutoMarginNombreSize.setEditable(selected);
});
panel.add(jCheckAutoMargin);
label = new JLabel(" 横");
label.setToolTipText("横方向の余白除去量の制限 左右の余白の合計");
panel.add(label);
jTextAutoMarginLimitH = new JTextField("15");
jTextAutoMarginLimitH.setToolTipText(label.getToolTipText());
jTextAutoMarginLimitH.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginLimitH.setInputVerifier(new IntegerInputVerifier(15, 0, 50));
jTextAutoMarginLimitH.setMaximumSize(text3);
jTextAutoMarginLimitH.setPreferredSize(text3);
jTextAutoMarginLimitH.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginLimitH.addFocusListener(new TextSelectFocusListener(jTextAutoMarginLimitH));
panel.add(jTextAutoMarginLimitH);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel(" 縦");
label.setToolTipText("縦方向の余白除去量の制限 上下の余白の合計");
panel.add(label);
jTextAutoMarginLimitV = new JTextField("15");
jTextAutoMarginLimitV.setToolTipText(label.getToolTipText());
jTextAutoMarginLimitV.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginLimitV.setInputVerifier(new IntegerInputVerifier(15, 0, 50));
jTextAutoMarginLimitV.setMaximumSize(text3);
jTextAutoMarginLimitV.setPreferredSize(text3);
jTextAutoMarginLimitV.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginLimitV.addFocusListener(new TextSelectFocusListener(jTextAutoMarginLimitV));
panel.add(jTextAutoMarginLimitV);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
panel.add(label);
label = new JLabel(" 余白追加");
label.setToolTipText("余白除去後に追加する余白の量(追加部分の画像はそのまま)");
panel.add(label);
jTextAutoMarginPadding = new JTextField("1.0");
jTextAutoMarginPadding.setToolTipText(label.getToolTipText());
jTextAutoMarginPadding.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginPadding.setInputVerifier(new FloatInputVerifier(1.0f, 0, 50));
jTextAutoMarginPadding.setMaximumSize(text3);
jTextAutoMarginPadding.setPreferredSize(text3);
jTextAutoMarginPadding.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginPadding.addFocusListener(new TextSelectFocusListener(jTextAutoMarginPadding));
panel.add(jTextAutoMarginPadding);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel(" 白レベル");
label.setToolTipText("余白部分の白い画素と判別するレベルを指定します (黒:0~白:100)");
panel.add(label);
jTextAutoMarginWhiteLevel = new JTextField("80");
jTextAutoMarginWhiteLevel.setToolTipText(label.getToolTipText());
jTextAutoMarginWhiteLevel.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginWhiteLevel.setInputVerifier(new IntegerInputVerifier(80, 0, 100));
jTextAutoMarginWhiteLevel.setMaximumSize(text3);
jTextAutoMarginWhiteLevel.setPreferredSize(text3);
jTextAutoMarginWhiteLevel.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginWhiteLevel.addFocusListener(new TextSelectFocusListener(jTextAutoMarginWhiteLevel));
panel.add(jTextAutoMarginWhiteLevel);
label = new JLabel("%");
label.setBorder(padding2H);
panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panelV.add(panel);
label = new JLabel("ノンブル除去 (位置");
label.setBorder(padding2H);
panel.add(label);
jComboAutoMarginNombre = new JComboBox<String>(new String[]{"なし","上","下","上下"});
jComboAutoMarginNombre.setToolTipText("ノンブルを除去します。除去した場合は除去制限が5%追加されます");
jComboAutoMarginNombre.setFocusable(false);
jComboAutoMarginNombre.setMaximumSize(new Dimension(text3.width+24, 20));
jComboAutoMarginNombre.setPreferredSize(new Dimension(text3.width+24, 20));
panel.add(jComboAutoMarginNombre);
label = new JLabel(" 高さ");
label.setBorder(padding2H);
panel.add(label);
jTextAutoMarginNombreSize = new JTextField("3.0");
jTextAutoMarginNombreSize.setToolTipText("ノンブルの文字部分の高さを指定します。これより大きい場合はノンブル除去されません");
jTextAutoMarginNombreSize.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginNombreSize.setInputVerifier(new FloatInputVerifier(3.0f, 0.5f, 10));
jTextAutoMarginNombreSize.setMaximumSize(text3);
jTextAutoMarginNombreSize.setPreferredSize(text3);
jTextAutoMarginNombreSize.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginNombreSize.addFocusListener(new TextSelectFocusListener(jTextAutoMarginPadding));
panel.add(jTextAutoMarginNombreSize);
label = new JLabel("% )");
label.setBorder(padding2H);
panel.add(label);
ChatGPT:
以下は、提示されたSwingの余白除去設定UIをAndroidのPreferenceScreenに変換したXML例です。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="余白除去"> <!-- 有効 --> <CheckBoxPreference android:key="trim_enabled" android:title="余白除去を有効にする" /> <!-- 横方向の制限 --> <EditTextPreference android:key="trim_limit_horizontal" android:title="横方向の制限 (%)" android:summary="横方向の余白除去量の制限 (左右の余白の合計)" android:defaultValue="15" android:inputType="number" /> <!-- 縦方向の制限 --> <EditTextPreference android:key="trim_limit_vertical" android:title="縦方向の制限 (%)" android:summary="縦方向の余白除去量の制限 (上下の余白の合計)" android:defaultValue="15" android:inputType="number" /> <!-- 余白追加 --> <EditTextPreference android:key="trim_padding" android:title="余白追加 (%)" android:summary="余白除去後に追加する余白の量(追加部分の画像はそのまま)" android:defaultValue="1.0" android:inputType="numberDecimal" /> <!-- 白レベル --> <EditTextPreference android:key="trim_white_level" android:title="白レベル (%)" android:summary="余白部分の白い画素と判別するレベル (黒:0~白:100)" android:defaultValue="80" android:inputType="number" /> <!-- ノンブル除去 --> <ListPreference android:key="trim_nombre_position" android:title="ノンブル除去 (位置)" android:summary="ノンブルを除去します。除去した場合は除去制限が5%追加されます" android:entries="@array/nombre_positions" android:entryValues="@array/nombre_values" android:defaultValue="none" /> <!-- ノンブルの高さ --> <EditTextPreference android:key="trim_nombre_height" android:title="ノンブル高さ (%)" android:summary="ノンブル文字部分の高さ。これより大きい場合は除去されません" android:defaultValue="3.0" android:inputType="numberDecimal" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="nombre_positions"> <item>なし</item> <item>上</item> <item>下</item> <item>上下</item> </string-array> <string-array name="nombre_values"> <item>none</item> <item>top</item> <item>bottom</item> <item>both</item> </string-array> </resources>
Swing版では jCheckAutoMargin の状態に応じて他の項目が有効/無効化されていました。Androidでも以下のように制御できます:
public class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.preferences_trim, rootKey); CheckBoxPreference enabledPref = findPreference("trim_enabled"); EditTextPreference hLimitPref = findPreference("trim_limit_horizontal"); EditTextPreference vLimitPref = findPreference("trim_limit_vertical"); EditTextPreference paddingPref = findPreference("trim_padding"); EditTextPreference whiteLevelPref = findPreference("trim_white_level"); EditTextPreference nombreHeightPref = findPreference("trim_nombre_height"); ListPreference nombrePosPref = findPreference("trim_nombre_position"); Preference.OnPreferenceChangeListener toggle = (pref, value) -> { boolean enabled = (Boolean) value; hLimitPref.setEnabled(enabled); vLimitPref.setEnabled(enabled); paddingPref.setEnabled(enabled); whiteLevelPref.setEnabled(enabled); nombreHeightPref.setEnabled(enabled); nombrePosPref.setEnabled(enabled); return true; }; if (enabledPref != null) { boolean init = enabledPref.isChecked(); toggle.onPreferenceChange(null, init); enabledPref.setOnPreferenceChangeListener(toggle); } } }
SwingのUIの構成がかなり詳細だったため、Android版でもできるだけツールチップや制限に相当する部分を反映させました。
次に別のセクション(たとえばページ回転やトリミング)も変換しますか?
あなた:
下記のコードをAndroidのpreferenceに書き換えて
////////////////////////////////
//余白除去
////////////////////////////////
panelV = new JPanel();
panelV.setLayout(new BoxLayout(panelV, BoxLayout.Y_AXIS));
panelV.setBorder(new NarrowTitledBorder("余白除去"));
tabPanel.add(panelV);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.setBorder(padding4B);
panelV.add(panel);
jCheckAutoMargin = new JCheckBox("有効 ");
jCheckAutoMargin.setFocusPainted(false);
jCheckAutoMargin.setBorder(padding2);
jCheckAutoMargin.setIconTextGap(2);
jCheckAutoMargin.addChangeListener(e -> {
boolean selected = jCheckAutoMargin.isSelected();
jTextAutoMarginLimitH.setEditable(selected);
jTextAutoMarginLimitV.setEditable(selected);
jTextAutoMarginWhiteLevel.setEditable(selected);
jTextAutoMarginPadding.setEditable(selected);
jTextAutoMarginNombreSize.setEditable(selected);
});
panel.add(jCheckAutoMargin);
label = new JLabel(" 横");
label.setToolTipText("横方向の余白除去量の制限 左右の余白の合計");
panel.add(label);
jTextAutoMarginLimitH = new JTextField("15");
jTextAutoMarginLimitH.setToolTipText(label.getToolTipText());
jTextAutoMarginLimitH.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginLimitH.setInputVerifier(new IntegerInputVerifier(15, 0, 50));
jTextAutoMarginLimitH.setMaximumSize(text3);
jTextAutoMarginLimitH.setPreferredSize(text3);
jTextAutoMarginLimitH.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginLimitH.addFocusListener(new TextSelectFocusListener(jTextAutoMarginLimitH));
panel.add(jTextAutoMarginLimitH);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel(" 縦");
label.setToolTipText("縦方向の余白除去量の制限 上下の余白の合計");
panel.add(label);
jTextAutoMarginLimitV = new JTextField("15");
jTextAutoMarginLimitV.setToolTipText(label.getToolTipText());
jTextAutoMarginLimitV.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginLimitV.setInputVerifier(new IntegerInputVerifier(15, 0, 50));
jTextAutoMarginLimitV.setMaximumSize(text3);
jTextAutoMarginLimitV.setPreferredSize(text3);
jTextAutoMarginLimitV.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginLimitV.addFocusListener(new TextSelectFocusListener(jTextAutoMarginLimitV));
panel.add(jTextAutoMarginLimitV);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
panel.add(label);
label = new JLabel(" 余白追加");
label.setToolTipText("余白除去後に追加する余白の量(追加部分の画像はそのまま)");
panel.add(label);
jTextAutoMarginPadding = new JTextField("1.0");
jTextAutoMarginPadding.setToolTipText(label.getToolTipText());
jTextAutoMarginPadding.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginPadding.setInputVerifier(new FloatInputVerifier(1.0f, 0, 50));
jTextAutoMarginPadding.setMaximumSize(text3);
jTextAutoMarginPadding.setPreferredSize(text3);
jTextAutoMarginPadding.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginPadding.addFocusListener(new TextSelectFocusListener(jTextAutoMarginPadding));
panel.add(jTextAutoMarginPadding);
label = new JLabel("%");
label.setBorder(padding2H);
panel.add(label);
label = new JLabel(" 白レベル");
label.setToolTipText("余白部分の白い画素と判別するレベルを指定します (黒:0~白:100)");
panel.add(label);
jTextAutoMarginWhiteLevel = new JTextField("80");
jTextAutoMarginWhiteLevel.setToolTipText(label.getToolTipText());
jTextAutoMarginWhiteLevel.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginWhiteLevel.setInputVerifier(new IntegerInputVerifier(80, 0, 100));
jTextAutoMarginWhiteLevel.setMaximumSize(text3);
jTextAutoMarginWhiteLevel.setPreferredSize(text3);
jTextAutoMarginWhiteLevel.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginWhiteLevel.addFocusListener(new TextSelectFocusListener(jTextAutoMarginWhiteLevel));
panel.add(jTextAutoMarginWhiteLevel);
label = new JLabel("%");
label.setBorder(padding2H);
panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panelV.add(panel);
label = new JLabel("ノンブル除去 (位置");
label.setBorder(padding2H);
panel.add(label);
jComboAutoMarginNombre = new JComboBox<String>(new String[]{"なし","上","下","上下"});
jComboAutoMarginNombre.setToolTipText("ノンブルを除去します。除去した場合は除去制限が5%追加されます");
jComboAutoMarginNombre.setFocusable(false);
jComboAutoMarginNombre.setMaximumSize(new Dimension(text3.width+24, 20));
jComboAutoMarginNombre.setPreferredSize(new Dimension(text3.width+24, 20));
panel.add(jComboAutoMarginNombre);
label = new JLabel(" 高さ");
label.setBorder(padding2H);
panel.add(label);
jTextAutoMarginNombreSize = new JTextField("3.0");
jTextAutoMarginNombreSize.setToolTipText("ノンブルの文字部分の高さを指定します。これより大きい場合はノンブル除去されません");
jTextAutoMarginNombreSize.setHorizontalAlignment(JTextField.RIGHT);
jTextAutoMarginNombreSize.setInputVerifier(new FloatInputVerifier(3.0f, 0.5f, 10));
jTextAutoMarginNombreSize.setMaximumSize(text3);
jTextAutoMarginNombreSize.setPreferredSize(text3);
jTextAutoMarginNombreSize.setEditable(jCheckAutoMargin.isSelected());
jTextAutoMarginNombreSize.addFocusListener(new TextSelectFocusListener(jTextAutoMarginPadding));
panel.add(jTextAutoMarginNombreSize);
label = new JLabel("% )");
label.setBorder(padding2H);
panel.add(label);
ChatGPT:
このSwingベースのUIコードをAndroidのPreferenceScreen(設定画面)に変換するには、以下のようにXMLとKotlin/Javaのコードを組み合わせて実装します。
Swing UI | Android Preference |
---|---|
JCheckBox | SwitchPreferenceCompat |
JTextField | EditTextPreference |
JComboBox | ListPreference |
JPanel | PreferenceCategoryまたはPreferenceScreen |
setEditable() | setEnabled() |
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="余白除去"> <SwitchPreferenceCompat android:key="auto_margin_enabled" android:title="有効" android:defaultValue="false" /> <EditTextPreference android:key="auto_margin_limit_h" android:title="横方向の余白除去量" android:dialogTitle="横方向の余白除去量 (%)" android:defaultValue="15" android:enabled="false" android:inputType="number" /> <EditTextPreference android:key="auto_margin_limit_v" android:title="縦方向の余白除去量" android:dialogTitle="縦方向の余白除去量 (%)" android:defaultValue="15" android:enabled="false" android:inputType="number" /> <EditTextPreference android:key="auto_margin_padding" android:title="余白追加量" android:dialogTitle="余白追加量 (%)" android:defaultValue="1.0" android:enabled="false" android:inputType="numberDecimal" /> <EditTextPreference android:key="auto_margin_white_level" android:title="白レベル" android:dialogTitle="白レベル (0〜100)" android:defaultValue="80" android:enabled="false" android:inputType="number" /> <ListPreference android:key="auto_margin_nombre_position" android:title="ノンブル除去位置" android:defaultValue="なし" android:entries="@array/nombre_position_entries" android:entryValues="@array/nombre_position_values" /> <EditTextPreference android:key="auto_margin_nombre_size" android:title="ノンブル高さ" android:dialogTitle="ノンブル高さ (%)" android:defaultValue="3.0" android:enabled="false" android:inputType="numberDecimal" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="nombre_position_entries"> <item>なし</item> <item>上</item> <item>下</item> <item>上下</item> </string-array> <string-array name="nombre_position_values"> <item>none</item> <item>top</item> <item>bottom</item> <item>both</item> </string-array> </resources>
class AutoMarginPreferenceFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences_auto_margin, rootKey) val enabledSwitch = findPreference<SwitchPreferenceCompat>("auto_margin_enabled") val dependentKeys = listOf( "auto_margin_limit_h", "auto_margin_limit_v", "auto_margin_padding", "auto_margin_white_level", "auto_margin_nombre_size" ) val updateDependentPrefs: (Boolean) -> Unit = { isEnabled -> dependentKeys.forEach { key -> findPreference<Preference>(key)?.isEnabled = isEnabled } } enabledSwitch?.setOnPreferenceChangeListener { _, newValue -> updateDependentPrefs(newValue as Boolean) true } // 初期状態の反映 enabledSwitch?.isChecked?.let { updateDependentPrefs(it) } } }
これで、Swingの「余白除去」UIがAndroidのPreference画面に変換されます。必要であれば、より詳細なバリデーション(0〜100制限など)や単位の表示も追加可能です。
要望があれば、単位表示を含んだカスタムViewの作成例などもお手伝いできますよ!
あなた:
javaで書いて
ChatGPT:
了解しました! 下記は、Swingの「余白除去」設定UIを AndroidのJavaベースのPreferenceFragmentCompat で実装した例です。Kotlinではなく、Javaで書き直しています。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="余白除去"> <SwitchPreferenceCompat android:key="auto_margin_enabled" android:title="有効" android:defaultValue="false" /> <EditTextPreference android:key="auto_margin_limit_h" android:title="横方向の余白除去量 (%)" android:defaultValue="15" android:enabled="false" android:inputType="number" /> <EditTextPreference android:key="auto_margin_limit_v" android:title="縦方向の余白除去量 (%)" android:defaultValue="15" android:enabled="false" android:inputType="number" /> <EditTextPreference android:key="auto_margin_padding" android:title="余白追加量 (%)" android:defaultValue="1.0" android:enabled="false" android:inputType="numberDecimal" /> <EditTextPreference android:key="auto_margin_white_level" android:title="白レベル (0〜100)" android:defaultValue="80" android:enabled="false" android:inputType="number" /> <ListPreference android:key="auto_margin_nombre_position" android:title="ノンブル除去位置" android:defaultValue="none" android:entries="@array/nombre_position_entries" android:entryValues="@array/nombre_position_values" /> <EditTextPreference android:key="auto_margin_nombre_size" android:title="ノンブル高さ (%)" android:defaultValue="3.0" android:enabled="false" android:inputType="numberDecimal" /> </PreferenceCategory> </PreferenceScreen>
<resources> <string-array name="nombre_position_entries"> <item>なし</item> <item>上</item> <item>下</item> <item>上下</item> </string-array> <string-array name="nombre_position_values"> <item>none</item> <item>top</item> <item>bottom</item> <item>both</item> </string-array> </resources>
public class AutoMarginPreferenceFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.preferences_auto_margin, rootKey); SwitchPreferenceCompat switchAutoMargin = findPreference("auto_margin_enabled"); String[] dependentKeys = new String[]{ "auto_margin_limit_h", "auto_margin_limit_v", "auto_margin_padding", "auto_margin_white_level", "auto_margin_nombre_size" }; if (switchAutoMargin != null) { boolean isEnabled = switchAutoMargin.isChecked(); updateDependents(dependentKeys, isEnabled); switchAutoMargin.setOnPreferenceChangeListener((preference, newValue) -> { updateDependents(dependentKeys, (Boolean) newValue); return true; }); } } private void updateDependents(String[] keys, boolean enabled) { for (String key : keys) { Preference pref = findPreference(key); if (pref != null) { pref.setEnabled(enabled); } } } }
<activity android:name=".SettingsActivity" />
public class SettingsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportFragmentManager() .beginTransaction() .replace(android.R.id.content, new AutoMarginPreferenceFragment()) .commit(); } }
これで、Swing UI の「余白除去」設定が Android の Preference 画面として Javaで完全に再現されます!
必要であれば、単位(%)の表示や入力制限ロジック(バリデーション)を追加するカスタムバージョンも用意できます。やってみますか?