【问题标题】:JavaFX Pane inside of a Tab选项卡内的 JavaFX 窗格
【发布时间】:2017-10-21 03:01:25
【问题描述】:

我想从窗格扩展一个类,然后使用TabPane 的选项卡中的setContent() 方法在此选项卡中显示窗格。当我从JPanel 扩展时,它在Swing 中工作,但如果我在JavaFX 中尝试类似的东西,它只会显示选项卡本身并在下面保持空白。

我想在不同的类中处理选项卡的内容,我在这里做错了吗?

摇摆版:

import java.awt.*;
import javax.swing.*;
import java.util.*;

public class Home extends JFrame{
  private JTabbedPane jTabbedPane1 = new JTabbedPane();
  private Example ex = new Example();

  public static void main(String[] args) {
    Home h1 = new Home();
    h1.ex= new Example();
    h1.jTabbedPane1.add("test",h1.ex);
  } // end of main

  public Home() { 
    // Frame-Initialisierung
    super();

    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

    setSize(200,200);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    setResizable(false);

    Container cp = getContentPane();
    cp.setLayout(null);
    // Anfang Komponenten

    jTabbedPane1.setBounds(0, 0, 100, 100);
    cp.add(jTabbedPane1);

    setVisible(true);
  } // end of public home
} // end of class Home

import java.awt.*;
import javax.swing.*;
import java.util.*;

public class Example extends JPanel {
  private JList jList1 = new JList();
  private DefaultListModel jList1Model = new DefaultListModel();
  private JScrollPane jList1ScrollPane = new JScrollPane(jList1);

  public Example(){
    super();
    setLayout(null);
    jList1.setModel(jList1Model);
    jList1ScrollPane.setBounds(0, 0, 100, 100);

    add(jList1ScrollPane);

    }

} // end of class Example

不适用于 JavaFX 版本:

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Home extends Application {


  private TabPane tabpane = new TabPane();
  private Example ex;

    @Override
    public void start(Stage primaryStage) {

     primaryStage.setTitle("TEST");

     Pane layout = new Pane();

     tabpane.setLayoutX(-8);
     tabpane.setLayoutY(24);
     tabpane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);

      Tab tab = new Tab();
      tab.setText("new tab");
      tab.setContent(new Rectangle(200,200));
      this.ex = new Example();
      tab.setContent(ex);
      tabpane.getTabs().add(tab);

     layout.getChildren().add(tabpane);

     Scene scene = new Scene(layout, 500, 500);


     scene.getStylesheets().clear();
     scene.getStylesheets().add(Home.class.getResource("style.css").toExternalForm());

     primaryStage.setScene(scene);
     primaryStage.setResizable(false);


     primaryStage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}



import java.util.ArrayList;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ListView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;



public class Example extends Pane{

     ListView<String> list = new ListView<String>();


    public void start(Stage primaryStage) {


     ArrayList<String> arraytest = new ArrayList<String>();
     arraytest.add("test1");
     arraytest.add("test2");

    ObservableList<String> test = FXCollections.observableArrayList(arraytest);

    list.setItems(test);
    list.setLayoutX(10);
    list.setLayoutY(10);
    list.setPrefWidth(270);
    list.setPrefHeight(270); 

     getChildren().add(list);

    }    
}

【问题讨论】:

  • 你是嵌入,比如this,还是移植?
  • 我刚刚从 JPanel 扩展了一个类,然后像 jTabbedPane.add("nameOfTheTab",ClassExtendedFromJPanel); 这样将它添加到 JTabbedPane 中
  • 听起来您想将现有的 Swing 程序移植到 JavaFX。请编辑您的问题,为 example 的原始 Swing 程序和尝试的 JavaFX 版本中的每一个添加一个 minimal reproducible example
  • 直接使用或扩展Pane相当于在Swing中做setLayout(null)。两者都是非常糟糕的想法。目前尚不清楚您要做什么,因为您的 JavaFX 代码正在将 List&lt;String&gt; 添加到窗格的子项中,这是不允许的,但我怀疑像 VBox 这样的标准布局可能会给您想要的东西;无需扩展任何标准 Java 类。
  • 赞誉不止一个,而是两个 minimal reproducible examples.

标签: java swing javafx


【解决方案1】:

您的 Swing 示例未正确同步,并受到 inflexible layout having absolute positioning 的影响。除了观察Pane“可以在需要绝对定位孩子的情况下直接使用”之外,该示例应被丢弃。在这种情况下,您的 JavaFX 示例不会。

在下面的 JavaFX 变体中,Example 构造所需的 ListView 并通过 getContent() 方法使其可用。 Home 然后将该内容用于选项卡。调整封闭舞台的大小以查看效果。

tab.setContent(example.getContent());

顺便说一句,private static class Example 在语义上等同于具有package-private 访问权限的类,这使得 原位测试 和随后重构为单独的类变得容易。

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.stage.Stage;

/** @see https://stackoverflow.com/a/44102580/230513 */
public class Home extends Application {

    private TabPane tabpane = new TabPane();
    private Example example = new Example();

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Test");
        tabpane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
        Tab tab = new Tab();
        tab.setText("Tab One");
        tab.setContent(example.getContent());
        tabpane.getTabs().add(tab);
        Scene scene = new Scene(tabpane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class Example {

        ListView<String> view = new ListView<>();

        public Example() {
            ObservableList<String> list = FXCollections.observableArrayList(
                "Test 1", "Test 2", "Test 3");
            view.setItems(list);
        }

        public ListView getContent() {
            return view;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【讨论】:

  • 哇!非常感谢您向我详细解释这一点。这很有帮助。对我帮助很大,因为我对编程还是很陌生。
  • 我的最后一个问题是如何在 Example 类中添加按钮之类的东西?我不能将它们添加到任何场景,因为它不使用窗格或类似的东西。
  • 而不是 getContent() 返回 ListView,让它返回一个合适的 Pane 子类,您已向其中添加了所需的控件。
  • 如果我将返回类型更改为 Pane 并将返回值更改为 return new Pane(); 只是为了测试这一点,如果我尝试运行代码会出现各种错误,但在 NetBeans 中编码时我没有显示错误..
  • 不是Pane,而是Pane子类,如AnchorPaneBorderPane
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 2022-01-26
相关资源
最近更新 更多