この人頭いいなと思ったエピソード

このカテゴリに初めて質問させて頂きます。使用しているJDKの
バージョンは1.4.2です。

今、JavaのSwingを利用してGUIアプリケーションを作成している
のですがJMenuに数十個のJMenuItemを配置させる必要があるの
ですが、大量のJMenuItemをJMenuに配置すると画面からはみ出
してしまいます。

そこで、JMenuで表示させるJMenuItemの数を制限し、それ以外
のJMenuItemはスクロールのような形で表示できるようにしたい
と思っているのですがこのような事は実現可能でしょうか?

A 回答 (5件)

直接的な回答にはなっていませんが、


その数十個のメニューは全てバラバラですか?
ある程度グループ分けできませんか?
グループ分けできるなら、グループのメニューの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の[表示]ー[サイズ]ー[大]みたいなサブメニューみたいになります。

質問者さんの希望には答えられてませんが、いかがでしょう?

この回答への補足

pcbegginerさん、レスどうもです。
サブメニュー化は私も考えたのですが結局、サブメニューの中に
数十個のJMenuItemが移動するだけでサブメニューが画面から
はみ出してしまうんですよねぇ。

それで何とかならないかなぁと思い、ここに質問した次第です。

補足日時:2005/04/13 22:39
    • good
    • 0

ごく基本的な考え方だけですが。



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で表示非表示を切り替えているだけですが、スクロールした「感じ」にはなると思います。
    • good
    • 0

 こんばんは。


 とりあえず、タイマーで動かすことにしてみました。
 それっぽく、動きます。
 ただ、適当に作ったので、表示するメニューの高さを適切に調整するとか、まだまだ作り込む余地があるのですが、ヒントにはなると思います。
 それにしても、なんでこの機能が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();
    }
  }
}
    • good
    • 0
この回答へのお礼

ym2です。

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

お礼日時:2005/04/14 15:59

 #3です。



 試行錯誤をしていたので、MouseAdapterのクラス名が妙なことになってますね。
 すみません。かえって混乱しますね。

 最初は#2さんの言われるような方法を考えていたのですが、私の環境(J2SE5.0)でJMenuにJButtonを登録すると、ActionEventがトリガされなかったので、しかたないので、JMenuItemにかえました。
 すると、クリックすると(当たり前の話ですが)メニューが消えてしまうので、マウスポインタが上に来ると、Timerをスタートさせて、Timerのイベントハンドラからスクロールさせるメソッドを呼ぶようにしました。

 とりあえず、50個のメニューのうち30個を表示するようになっていますが、環境によって、ちょうど言い数は違ってくるので、これを動的に変えるようにしなくてはいけないのですが、めんどくさいのでやっていません。

 そこら辺のことをちゃんと考えて、ScrollableMenu みたいなクラスを作っておけば、便利でいいのでしょうが・・・。
 がんばってください。
    • good
    • 0

#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();
}
}
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!