8

やや不明確な質問に対するお詫び-それを置くためのより良い方法を考えることができませんでした。

JXTaskPane(Swing labs拡張APIから)を使用して、いくつかの情報を表示します。

ユーザーはタイトルを「クリック」してパネルを展開できます。JXTaskPaneはコンテナJPanelにあり、メインアプリケーションウィンドウであるJFrameに追加されます。

アプリケーションウィンドウを展開された作業ウィンドウのサイズにサイズ変更したい。これを実現するために、コンテナJPanelにコンポーネントリスナーを追加しました。これにより、サイズが拡張されたパネルに設定されます。

panel.addComponentListener(new ComponentListener()
{   
    public void componentResized(ComponentEvent e)
    {
        Dimension newSize = ((JXTaskPane)e.getSource()).getSize();
        reSizeFrame(newSize);
    }
}

private void reSizeFrame(Dimension newSize)
{   
    if ((newSize.height < maxSize.height) && (newSize.width < maxSize.width))
    {
        containerPanel.setSize(newSize);
        appFrame.setSize(containerPanel.getSize());
        appFrame.pack();
    }
}

問題は、作業ウィンドウが展開されるときにcomponentResizedメソッドが呼び出されることです。その結果、resizeFrameメソッドが何度も呼び出され、画面上で非常にひどく見えます。

JXTaskpaneがサイズ変更を終了したことをどのように検出できますか?私は2つのアプローチを考えました:

  • resizeFrame()メソッドをSwingUtilities.invokeLate(..)呼び出しに配置します。

  • タイマーのresizeFrame呼び出しを行うと、後続の呼び出しはタイマーが起動するまで何も実行されません。これにより、パネルのサイズを変更するのに十分な時間が与えられます。

前進するための最良の方法は何ですか?

また-これは、何年にもわたるサーバーサイドプログラムの後の私の最初の本格的なJavaGUIアプリです。StackOverflowは非常に役に立ちました。ほんとありがと!

4

3 に答える 3

9

あなたがすでに答えを選択していることは知っていますが、ペイント方法をオーバーライドすることは間違いなく正しくありません。その場で何かをハックすることはできるかもしれませんが、それは理想的ではありません。

JXTaskPaneのソースを確認し、特にsetExpanded()(387行目)を確認すると、JXCollapsiblePane.setCollapsed(...)が呼び出され、拡張のプロパティ変更イベントが発生することがわかります。そのプロパティのリスナーは、アニメーションが完了する前に起動するため、正しくありません。したがって、JXCollapsiblePaneに入るとsetCollapsed(...)(470行目)を見ると、アニメーション化されている場合、パラメーターが設定され、タイマーが開始されていることがわかります。アニメーションがいつ終了するかを知りたいので、そのファイルでアニメーター(620行目、具体的には652-667行目)を見てください。アニメーションが終了すると、ANIMATION_STATE_KEYのプロパティが「collapsed」の値で変更されます。 「または「拡張」。これはあなたが実際に望むイベントです。ただし、JXCollapsiblePaneにアクセスできないため、JXTaskPaneに戻ってANIMATION_STATE_KEYを検索すると、208行目が見つかります。これは、JXTaskPaneがJXCollapsiblePane.ANIMATION_STATE_KEYにリスナーを作成し、それを独自のイベントとして再起動することを示しています。

JXTaskPaneにアクセスできるので、そのイベントをリッスンできます。

taskPane.addPropertyChangeListener(JXCollapsiblePane.ANIMATION_STATE_KEY, new PropertyChangeListener() {
  public void propertyChange(PropertyChangeEvent e) {
    if(e.getNewValue().equals("expanded") {
      ...
    }
    else if(e.getNewValue().equals("collapsed") {
      ...
    }
  }
}

必要なときに正確にイベントを取得する必要があります。

Swingでイベントをリッスンする正しい方法は、プロパティリスナーを使用することです。残念ながら、正しいプロパティと値を見つける唯一の方法は、ソースコードを掘り下げることです。

于 2010-03-01T00:43:55.597 に答える
1

提案として、最初にsuperを呼び出し、次にサイズが大幅に変更された場合にのみ、その最後にサイズ変更コードを配置して、paintメソッドをオーバーライドしてみましたか。

于 2010-02-26T10:52:16.677 に答える
1

私はJXTaskPaneに精通していませんが、私の最初の反応は、おそらくあなたが間違ったイベントを処理しているということです。ユーザーがヘッダーをクリックしたときにフレームのサイズを変更したいので、そのイベントを処理してみませんか(おそらく、作業ウィンドウのサイズが変更された後、EventQueue.invokeLater()を使用してフレームのサイズを変更します)。

しかし、それが機能せず、上記で概説したアプローチを使用する必要がある場合は、javax.swing.Timerを使用するのがおそらく最善です。200ミリ秒程度に設定し、componentResized()が起動するたびにrestart()するだけです。

于 2010-03-01T00:21:20.113 に答える