• ベストアンサー

SwingのJMenuに大量のJMenuItemを配置した場合の表示方法

このカテゴリに初めて質問させて頂きます。使用しているJDKの バージョンは1.4.2です。 今、JavaのSwingを利用してGUIアプリケーションを作成している のですがJMenuに数十個のJMenuItemを配置させる必要があるの ですが、大量のJMenuItemをJMenuに配置すると画面からはみ出 してしまいます。 そこで、JMenuで表示させるJMenuItemの数を制限し、それ以外 のJMenuItemはスクロールのような形で表示できるようにしたい と思っているのですがこのような事は実現可能でしょうか?

  • ym2
  • お礼率28% (2/7)
  • Java
  • 回答数5
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.3

 こんばんは。  とりあえず、タイマーで動かすことにしてみました。  それっぽく、動きます。  ただ、適当に作ったので、表示するメニューの高さを適切に調整するとか、まだまだ作り込む余地があるのですが、ヒントにはなると思います。  それにしても、なんでこの機能がSwingにないのでしょうねぇ。  不便です。 (コンパイルするときは全角スペースを半角スペースに変換してからにしてください) import javax.swing.*; import java.awt.event.*; public class Test extends JFrame {   JMenuBar menubar;   JMenu menuFile;   JMenuItem upButton;   JMenuItem downButton;   Timer timer;   boolean up;      public static void main(String[] args) {     Test frame = new Test();     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     frame.setSize(300, 200);     frame.setVisible(true);   }      public Test() {     timer = new Timer(500, new Timer_Action());     menubar = new JMenuBar();     menuFile = new JMenu("ファイル(F)");     upButton = new JMenuItem("▲");     Scroll_Clicked sc = new Scroll_Clicked();     upButton.addMouseListener(sc);          downButton = new JMenuItem("▼");     downButton.addMouseListener(sc);          setJMenuBar(menubar);     menubar.add(menuFile);     menuFile.add(upButton);     for (int i = 0; i < 50; i++) {       JMenuItem item = new JMenuItem("メニュー" + Integer.toString(i));       if (i > 30)         item.setVisible(false);       menuFile.add(item);     }     menuFile.add(downButton);   }      private void scrollUp() {     for (int i = 1; i < menuFile.getItemCount() - 30; i++) {       if (menuFile.getItem(i).isVisible()) {         menuFile.getItem(i).setVisible(false);         menuFile.getItem(i + 30).setVisible(true);         return;       }     }     timer.stop();   }      private void scrollDown() {     for (int i = menuFile.getItemCount() - 2; i > 30; i--) {       if (menuFile.getItem(i).isVisible()) {         menuFile.getItem(i).setVisible(false);         menuFile.getItem(i - 30).setVisible(true);         return;       }     }     timer.stop();   }      private class Scroll_Clicked extends MouseAdapter {     public void mouseEntered(MouseEvent e) {       Object source = e.getSource();       if (source == upButton)         up = true;       else         up = false;                timer.start();     }          public void mouseExited(MouseEvent e) {       timer.stop();     }   }      private class Timer_Action implements ActionListener {     public void actionPerformed(ActionEvent e) {       if (up)         scrollUp();       else         scrollDown();     }   } }

ym2
質問者

お礼

ym2です。 PecoPlusさん、わざわざソースコードまで載せて頂いて感謝 です。こういうときにもTimerが使えるとは思いつきませんでした。 これで上手い具合にMenuItemの表示を制御できるようになりました。

その他の回答 (4)

回答No.5

#1です。 #2さんの方法が自分には衝撃的だったので、試しました。 うまくいきました。感動しました。 #2さん、ありがとうございます。勉強になりました。 自分の環境は1.3.0_01と古い?ので、他の方とバージョンが違うのでもしかしたら動かないかもしれません。 稚拙なコードですが、いちおう貼り付けておきます。 (って全部表示できるかな…) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class MenuTest extends JFrame implements ActionListener{ private int begin = 0; private int end = 4; private JButton up = new JButton("▲"); private JButton down = new JButton("▼"); private JMenuItem[] items = new JMenuItem[10]; public MenuTest(){ super(); JMenu menu = new JMenu("hoge"); JMenuBar menubar = new JMenuBar(); menubar.add(menu); up.addActionListener(this); down.addActionListener(this); menu.add(up); for(int i = 0;i < items.length;i++){ items[i] = new JMenuItem(""+i); items[i].addActionListener(this); menu.add(items[i]); } menu.add(down); setJMenuBar(menubar); setSize(200,200); setVisible(true); items[0].setVisible(true); items[1].setVisible(true); items[2].setVisible(true); items[3].setVisible(true); items[4].setVisible(true); items[5].setVisible(false); items[6].setVisible(false); items[7].setVisible(false); items[8].setVisible(false); items[9].setVisible(false); } public void actionPerformed(ActionEvent e){ String command = e.getActionCommand(); System.out.println("アクションコマンド:"+command); if(command.equals("▲")){ if(begin != 0){ items[begin-1].setVisible(true); items[end].setVisible(false); begin = begin-1; end = end-1; } }else if(command.equals("▼")){ if(end != 9){ items[begin].setVisible(false); items[end+1].setVisible(true); begin = begin+1; end = end+1; } }else{ System.out.println("なにもしない"); } } public static void main(String[] args){ MenuTest mt = new MenuTest(); } }

  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.4

 #3です。  試行錯誤をしていたので、MouseAdapterのクラス名が妙なことになってますね。  すみません。かえって混乱しますね。  最初は#2さんの言われるような方法を考えていたのですが、私の環境(J2SE5.0)でJMenuにJButtonを登録すると、ActionEventがトリガされなかったので、しかたないので、JMenuItemにかえました。  すると、クリックすると(当たり前の話ですが)メニューが消えてしまうので、マウスポインタが上に来ると、Timerをスタートさせて、Timerのイベントハンドラからスクロールさせるメソッドを呼ぶようにしました。  とりあえず、50個のメニューのうち30個を表示するようになっていますが、環境によって、ちょうど言い数は違ってくるので、これを動的に変えるようにしなくてはいけないのですが、めんどくさいのでやっていません。  そこら辺のことをちゃんと考えて、ScrollableMenu みたいなクラスを作っておけば、便利でいいのでしょうが・・・。  がんばってください。

noname#49664
noname#49664
回答No.2

ごく基本的な考え方だけですが。 1.JButtonを2つ用意します。上向きのスクロール用、下向きのスクロール用です。 2.JMenuを作成し、上向きスクロールのJButton、続いてJMenuItemを必要なだけ、最後に下向きスクロールのJButtonをaddします。つまり、2つのJButtonの間にJMenuItemがずら~っと並ぶようにするわけです。 3.一番最初のJMenuItemから、表示させる数だけのJMenuItemをsetVisible(true)し、それ以後のものをすべてsetVisible(false)します。 4.上向きのJButtonのactionPerformedでは、表示されている一番下のJMenuItemを非表示にし、一番上のJMenuItemの1つ上のものを表示させます。 5.下向きのJButtonでは、反対に表示されている一番上のものを非表示にし、一番下の更に1つ下のものを表示させます。 ざっとこんな感じで上下にスクロールするメニューができると思います。 要するにsetVisibleで表示非表示を切り替えているだけですが、スクロールした「感じ」にはなると思います。

回答No.1

直接的な回答にはなっていませんが、 その数十個のメニューは全てバラバラですか? ある程度グループ分けできませんか? グループ分けできるなら、グループのメニューのJMenuクラスを生成して、 JMenuクラスのadd(JMenuItem menuItem)メソッドで追加すればいいのでは? JMenuクラスはJMenuItemクラスのサブクラスなのでaddできますよ。 例 JMenu view = new JMenu("表示"); JMenu size = new JMenu("サイズ"); JMenuItem l = new JMenuItem("大"); JMenuItem m = new JMenuItem("中"); JMenuItem s = new JMneuItem("小"); size.add(l); size.add(m); size.add(s); view.add(size); これで例えばIEの[表示]ー[サイズ]ー[大]みたいなサブメニューみたいになります。 質問者さんの希望には答えられてませんが、いかがでしょう?

ym2
質問者

補足

pcbegginerさん、レスどうもです。 サブメニュー化は私も考えたのですが結局、サブメニューの中に 数十個のJMenuItemが移動するだけでサブメニューが画面から はみ出してしまうんですよねぇ。 それで何とかならないかなぁと思い、ここに質問した次第です。

関連するQ&A

  • SWINGについて

    最近javaの勉強を始めた者です。今SWINGについて興味を持っているんですがふと「どこで使われているんだろう」と思いました。配布されているアプリケーションでは見たことがありませんし、「GUIが低品質」というのも聞いたことありますのでいまいち有効性が初心者の私にはわかりません。「これだから素人は困るよな」と思われるのを承知で質問しました。よろしければSWINGの実用性、またはこんなところでSWINGは使われているよ等教えてくれませんか?

    • ベストアンサー
    • Java
  • JavaのMenuItemをプログラムから表示させる方法

     JavaのMenuItemはMenuをクリックしないと表示しません。クリックしないでプログラムから表示させる方法を教えてください。ソースレベルで具体的にお願いいたしまーす。(Javaがよくわかってないので。)(JMenu、JMenuItemのほうでも可)

  • staticではないメソッドadd(Comp・・・

    コンパイルエラーが出ました。 かたほうのソース”A”では、add(p)で通るんですが、もう一方のソース”At”は、通りませんなぜでしょうか? 教えて下さい ↓”A”(通るほう) import javax.swing.*; import java.awt.event.*; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.border.LineBorder; import java.awt.*; public class A extends JFrame implements ActionListener { public static void main(String args[]) { A a = new A(); a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); a.setBounds(200,200,400,200); JMenuBar menubar = new JMenuBar(); LineBorder border = new LineBorder(Color.black,2, true); menubar.setBorder(border); JMenu menu1 = new JMenu("ファイル"); JMenu menu2 = new JMenu("エディット"); JMenu menu3 = new JMenu("編集"); JMenu menu4 = new JMenu("ヘルプ"); menubar.add(menu1); menubar.add(menu2); menubar.add(menu3); menubar.add(menu4); JMenuItem menuitem1 = new JMenuItem("新しく作る"); JMenuItem menuitem2 = new JMenuItem("続きから作る"); JMenuItem menuitem3 = new JMenuItem("ヘルプの表示"); menu1.add(menuitem1); menu1.add(menuitem2); menu4.add(menuitem3); a.setJMenuBar(menubar); a.setVisible(true); } A() { super("A"); JLabel l = new JLabel(""); JButton b = new JButton("PUSH"); b.addActionListener(this); JPanel p = new JPanel(); p.setBackground(Color.green); p.add(b); p.add(l); add(p);       ←ここ } public void actionPerformed(ActionEvent e) { System.out.println("A"); } } ___________________________________________________________________________________________________________________________________________________ ↓”At” import javax.swing.*; import java.awt.*; import java.awt.event.*; public class At extends JFrame { public static void main(String args[]) { At at = new At(); at.setBounds(200,200,400,200); at.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); at.setVisible(true); JButton b1 = new JButton("JButton1"); JButton b2 = new JButton("JButton2"); JButton b3 = new JButton("JButton3"); JPanel p = new JPanel(); p.setBackground(Color.red); b1.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e) { JLabel l = new JLabel("JBUTTON!1"); } } ); p.add(b1); p.add(b2); p.add(b3); add(p);         ←ここ } }

    • ベストアンサー
    • Java
  • 実験 課題 Java Swing 教えてください

    学校のPBL(問題解決学習?)でファイル操作関係のJavaアプリケーションを作る事になりました。 PBLから説明しますと、おおまかな課題が出題されて、それに則した課題を自分たち(4人の班)で決めてそれを解決する。みたいなものです。なので、テンプレみたいなものはなく、答えもありません。 世界的なシェアやこれから使えるかなーと思ってJavaで作ることにしました。が、学校の授業で習ったのはせいぜいJava入門書(やさ○いJava)程度で、アプリケーションを作れるような知識はほぼありません。 自分はGUIを任されたのですが、swingを学びながら少しずつ進んでいるところです。 ここで、一気に質問の本題に入ります。 操作するファイルのリストを表示してソートなどの機能をつけるのですが、Windowsのエクスプローラのファイルなどが表示されている部分のすぐ上の 名前 |更新日時 | 種類 | サイズ みたいなバー?はSwingのコンポーネントで作れますか? ソートの機能もそこに付けたい(Windowsのように)のですが、ラベルとボタンを組み合わせるのでしょうか?

    • ベストアンサー
    • Java
  • javaでGUI

    javaでGUIのアプリケーションやゲームを作る場合、swingやEclipseといったものがあるようなのですが、どちらを使えばよいのでしょうか?swingはもう古い、と聞いたのですがどうなのでしょうか。。。また、お勧めの書籍などはあるでしょうか? javaの基礎は一通りやったのですが、GUIについてはまだ勉強していません。わかるかた教えてください。お願いします。

    • ベストアンサー
    • Java
  • JavaでGUIアプリケーション

    JavaでGUIのアプリケーションを作成するには以前であればSwingが良いようですが、現在は何が良いのでしょうか? 作りたいのはデスクトップアプリケーションです。 アマゾンではSwingの本は古いのしかないようですがどうなのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • Swingなしで画像ファイルロード

    AWTを使ってJAVAのアプリケーションを作っています。 単純に画像ファイルを開いてウィンドウに表示するものを作りたいです。 しかし、画像ファイルを開く場合、必ずSwingがいるようなのです。 サンプルを探してもこんなのばかり。 ImageIcon icon=new ImageIcon("hoge.jpg"); Image img=icon.getImage(); このとき、ImageIconはSwingの部品なので、イヤなんです。 Swing未満のものを使って、画像をファイルから読み込んでImageオブジェクトをつくれないものでしょうか。

    • ベストアンサー
    • Java
  • classファイルが起動しない

    classファイルをhtml内で起動したところ、クラスファイルが生成できないとjava実行時にエラーが発生します。プログラムのどこが悪いのでしょうか? <プログラム> import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.*; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; public abstract class jyusyo1 extends JApplet implements ListSelectionListener, ItemListener { /* member class not found */ class MyListener {} public jyusyo1() { jmenubar = new JMenuBar(); jmenu1 = new JMenu("\u691C\u7D22"); jmenuitem1 = new JMenuItem("\u6F22\u5B57\u4F4F\u6240"); jmenuitem2 = new JMenuItem("\u30AB\u30CA\u4F4F\u6240"); jmenuitem3 = new JMenuItem("\u4F4F\u6240\u30B3\u30FC\u30C9"); jmenuitem4 = new JMenuItem("\u90F5\u4FBF\u756A\u53F7"); c = new JComboBox(); outString = ""; L = new JList(); items = new String[1]; defaulttablemodel = new DefaultTableModel(); t1 = new JTable(defaulttablemodel); } public void init() { String s = new String(); int i = 0; JFrame jframe = new JFrame(); jframe.setTitle("\u4F4F\u6240\u691C\u7D22"); jframe.setDefaultCloseOperation(3); JPanel jpanel = new JPanel(); jpanel.setLayout(new BorderLayout()); Container container = getContentPane(); for(int j = 0; j < 5; j++) defaulttablemodel.addColumn(str3[j]); try { BufferedReader bufferedreader = new BufferedReader(new FileReader("ken.dat")); while(bufferedreader.ready()) { try { String s1 = bufferedreader.readLine(); c.addItem(s1); i++; continue; } catch(EOFException eofexception) { bufferedreader.close(); } break; } } catch(Exception exception) { System.err.println(exception); } container.add(c); c.addItemListener(this); setLayout(new BorderLayout()); JScrollPane jscrollpane = new JScrollPane(L); L.setVisibleRowCount(10); L.setSelectionMode(0); L.addListSelectionListener(this); container.add(jscrollpane); } public void valueChanged(ListSelectionEvent listselectionevent) { } public abstract void itemStateChanged(ItemEvent itemevent); JMenuBar jmenubar; JMenu jmenu1; JMenuItem jmenuitem1; JMenuItem jmenuitem2; JMenuItem jmenuitem3; JMenuItem jmenuitem4; JComboBox c; String outString; JList L; String items[]; DefaultTableModel defaulttablemodel; JTable t1; String str3[] = { "\u30B3\u30FC\u30C9", "\u65B0\u90F5\u756A", "\u4F4F\u6240\uFF13", "\u4F4F\u6240\uFF14", "\u65E5\u4ED8" }; }

  • fvwmでウィンドウを自動的に配置する方法

    質問します。 ウィンドウマネージャ"fvwm"で、自動的にGUIアプリケーションを配置する方法を探しています。 条件として、複数のGUIアプリケーションを起動した際に、ウィンドウを重ねずに表示させたいです。どうしてもウィンドウが重なる場合は、重ねる部分を可能なかぎり少なくしたいです。 RandomPlaecementとSmartPlacementを使用してみましたが、ウィンドウを重ねて表示する場合に、ウィンドウの重なった部分が大きいので使用できません。 どなたか解決策をご存知ないでしょうか。 お知恵をお貸しください。

  • GUIアプリケーションのテスト

    Javaの初心者です。 Swingを利用してGUIアプリケーションを作成しているのですが、 GUIで作成したプログラムをテストするには、全て手動で行わなければ ならないのでしょうか? それとも何か試験ツールのようなものがあるのでしょうか?

専門家に質問してみよう