【问题标题】:How to update new tab title?如何更新新标签标题?
【发布时间】:2016-12-13 14:16:39
【问题描述】:

我正在尝试在 java swing 中构建一个 web 浏览器,我通过添加 JTabbedPane 添加了新的选项卡选项。但是当我浏览另一个网页或网址等时,我想更新我当前的标签标题。我使用 WebViewWebEngine 作为 html 解析器。我尝试使用WebEngine.getTitle() 更新标题名称,但没有成功。

这是我的构造函数:

public class Hello extends JFrame {

private JButton backButton = new JButton();
private JButton newPage;
private JButton forwardButton = new JButton();
private JFXPanel jfxPanel = new JFXPanel();
private JTextField locationTextField = new JTextField(100);
private JPanel fPane = new JPanel(new BorderLayout());
private JPanel totalPane = new JPanel(new BorderLayout());
private WebEngine engine;
JPanel buttonPanel = new JPanel(new BorderLayout());
public ArrayList<String> pageList = new ArrayList<>();
public ArrayList<String> historyList = new ArrayList<>();
static int value = 0;
static int inI = 0;
public ArrayList<String> title = new ArrayList<>();
public ArrayList<String> titleUrl = new ArrayList<>();
Hashtable<String, String> table;
History hist;
final JTabbedPane tb;
private GraphicsDevice device;
private JFrame frame;

public Hello() {
    currentScene();
    table = new Hashtable<>();
    setResizable(true);
    setTitle("Pooh");
    ImageIcon img = new ImageIcon(Hello.class.getResource("/Panda-icon.png"));
    setIconImage(img.getImage());
    JPanel buttonPanel1 = new JPanel();
    buttonPanel1.setBackground(Color.decode("#330300"));

    backButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            BorderFactory.createRaisedBevelBorder();
            actionBack();
            System.out.println(value + " " + pageList.size() + " back");
        }
    });
    backButton.setEnabled(true);
    backButton.setBorderPainted(false);
    buttonPanel1.add(backButton);

    forwardButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (pageList.size() > value) {
                value++;
            }
            System.out.println(value + "forwad");
            actionForward();
        }
    });
    forwardButton.setEnabled(true);

    locationTextField.addKeyListener(new KeyAdapter() {
        public void keyReleased(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                value++;
                String tUrl = toURL(locationTextField.getText());
                actionGo(locationTextField.getText());
            }
        }
    });
    locationTextField.setDragEnabled(true);
    buttonPanel1.add(locationTextField, BorderLayout.EAST);
    JPanel buttonPanel2 = new JPanel(new BorderLayout(5, 5));
    buttonPanel2.setBackground(Color.decode("#330300"));

    newPage = new JButton();
    newPage.setIcon(new ImageIcon(Hello.class.getResource("/Plus.png")));
    newPage.setPreferredSize(new Dimension(30,30));
    newPage.setBorderPainted(false);
    newPage.setBackground(Color.decode("#330300"));
    newPage.setToolTipText("New Page");
    newPage.setEnabled(true);

    buttonPanel2.add(newPage,BorderLayout.CENTER);

    buttonPanel.setBackground(Color.decode("#330300"));
    buttonPanel.add(buttonPanel1, BorderLayout.WEST);
    buttonPanel.add(buttonPanel2, BorderLayout.EAST);

    JPanel lblBar = new JPanel(new BorderLayout());
    lblBar.setPreferredSize(new Dimension(50,10));
    JPanel jp = new JPanel();
    jp.setLayout(new BorderLayout());
    UIManager.put("TabbedPane.background",Color.decode("#330300"));
    tb = new JTabbedPane();
    tb.setUI(new CustomTabbedPaneUI());
    tb.setForeground(Color.decode("#330300"));
    **//creating initial tab with default name "Google" which i want to change when new urls are clicked**
    tb.addTab("Google",fPane);
    jp.add(new JLayer<JTabbedPane>(tb));
    **//creating new tabs when button is clicked**
    newPage.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
          tb.addTab("New Tab",new JPanel());
          **//a method which takes index of tabbed pane and returns a tabbed pane**
          initTabComponent(inI+1);
            inI++;
        }
    });
    tb.setOpaque(true);
    fPane.add(jfxPanel,BorderLayout.CENTER);
    totalPane.add(buttonPanel, BorderLayout.NORTH);
    totalPane.add(jp, BorderLayout.CENTER);
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setLayout(new BorderLayout());
    getContentPane().add(totalPane,BorderLayout.CENTER);
    getContentPane().add(lblStatus,BorderLayout.PAGE_END);
    setPreferredSize(new Dimension(1024, 600));
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
}
}

这是我的currentScene() 方法:

private void currentScene() {

    Platform.runLater(new Runnable() {
        @Override
        public void run() {

            WebView view = new WebView();
            engine = view.getEngine();

            engine.createPopupHandlerProperty();
            engine.titleProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            Hello.this.setTitle(newValue);
                            if (newValue != null) {
                                table.put(newValue, tUrl);
                                title.add(newValue);
                                historyList.add(newValue);
                                 pageList.add(tUrl);
                            }

                        }
                    });
                }
            });

            engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
                @Override
                public void handle(final WebEvent<String> event) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            lblStatus.setText(event.getData());
                        }
                    });
                }
            });

            engine.locationProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            titleUrl.add(newValue);
                            locationTextField.setText(newValue);
                        }
                    });
                }
            });

            engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            progressBar.setValue(newValue.intValue());
                        }
                    });
                }
            });
            engine.getLoadWorker()
                    .exceptionProperty()
                    .addListener(new ChangeListener<Throwable>() {

                        public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) {
                            if (engine.getLoadWorker().getState() == FAILED) {
                                SwingUtilities.invokeLater(new Runnable() {
                                    @Override
                                    public void run() {
                                        JOptionPane.showMessageDialog(
                                                fPane,
                                                (value != null)
                                                        ? engine.getLocation() + "\n" + value.getMessage()
                                                        : engine.getLocation() + "\nUnexpected error.",
                                                "Loading error...",
                                                JOptionPane.ERROR_MESSAGE);
                                    }
                                });
                            }
                        }
                    });

            jfxPanel.setScene(new Scene(view));
        }
    });
}

【问题讨论】:

  • 请编辑您的问题并包含 Hello 类的 setTitle 方法的代码。
  • Hello() 在这里扩展 JFrame
  • 啊。好吧,在 JFrame 上调用 setTitle 不会改变选项卡的标题,是吗?您是否扫描了javadoc 中的方法摘要,以查找用于设置选项卡标题的方法?
  • 谢谢,我实际上想动态更新选项卡的标题名称,你能告诉我应该把更改放在哪里吗?
  • 将代码放在您的 ChangeListener 中,在其他标题更新旁边。

标签: java swing jtabbedpane javafx-webengine jwebbrowser


【解决方案1】:

您需要在 JTabbedPane 上调用 setTitleAt(...) 来更改选项卡的标题。

【讨论】:

    【解决方案2】:

    我更喜欢 CloseableTabbedPane 。它具有带有标签标题和图标的方法 addTab 你可以在这里下载它https://github.com/dimensionv/closeabletabbedpane

    package de.dimensionv.java.gui.swing.panels;
    
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import javax.swing.Icon;
    
    /**
     * Draws an icon representing an "X" in a box. The constructor accepts an icon, which will be placed next (right) to the
     * 'X' icon drawn by this class. If no extra icon is needed, the empty default constructor can be used, or provide
     * "null" as a value for the icon-object.
     *
     * @author mjoellnir
     * @version 1.0
     */
    public class CloseTabIcon implements Icon {
    
      private int xPos;
      private int yPos;
      private int width = 16;
      private int height = 16;
      private final int offsetFrame = 2;
      private final int offsetCross1 = 3;
      private final int offsetCross2 = 4;
      private Icon extraIcon = null;
    
      /**
       * Creates new "X" Icon.
       */
      public CloseTabIcon() {
      }
    
      /**
       * Creates new "X" Icon with an extra icon next to it.
       *
       * @param fileIcon the Icon-object to be placed next to this icon.
       * @see javax.swing.Icon
       */
      public CloseTabIcon(Icon fileIcon) {
        extraIcon = fileIcon;
      }
    
      @Override
      public void paintIcon(Component component, Graphics graphics, int x, int y) {
        setXPos(x);
        setYPos(y);
    
        Color col = graphics.getColor();
    
        graphics.setColor(Color.black);
    
        // prepare coordinates for the frame...
        int frameTop = y + offsetFrame;
        int frameBottom = y + (height - offsetFrame);
        int frameLeft = x + offsetFrame;
        int frameRight = x + (width - offsetFrame);
    
        // top line of rectangle-frame...
        graphics.drawLine(frameLeft + 2, frameTop, frameRight - 2, frameTop);
        // bottom line of rectangle-frame...
        graphics.drawLine(frameLeft + 2, frameBottom, frameRight - 2, frameBottom);
        // left line of rectangle-frame...
        graphics.drawLine(frameLeft, frameTop + 2, frameLeft, frameBottom - 2);
        // right line of rectangle-frame...
        graphics.drawLine(frameRight, frameTop + 2, frameRight, frameBottom - 2);
    
        // rounding
        graphics.drawLine(frameLeft + 1, frameTop + 1, frameLeft + 1, frameTop + 1);
        graphics.drawLine(frameRight - 1, frameTop + 1, frameRight - 1, frameTop + 1);
        graphics.drawLine(frameLeft + 1, frameBottom - 1, frameLeft + 1, frameBottom - 1);
        graphics.drawLine(frameRight - 1, frameBottom - 1, frameRight - 1, frameBottom - 1);
    
        // prepare coordinates for the "X"
        int crossTop1 = frameTop + offsetCross1;
        int crossBottom1 = frameBottom - offsetCross1;
        int crossTop2 = frameTop + offsetCross2;
        int crossBottom2 = frameBottom - offsetCross2;
    
        int crossRight1 = frameRight - offsetCross1;
        int crossLeft1 = frameLeft + offsetCross1;
        int crossRight2 = frameRight - offsetCross2;
        int crossLeft2 = frameLeft + offsetCross2;
    
        // first diagonal of "X": top left to bottom right...
        graphics.drawLine(crossLeft1, crossTop1, crossRight1, crossBottom1);
        graphics.drawLine(crossLeft1, crossTop2, crossRight2, crossBottom1);
        graphics.drawLine(crossLeft2, crossTop1, crossRight1, crossBottom2);
    
        // second diagonal of "X": top right to bottom left...
        graphics.drawLine(crossRight1, crossTop1, crossLeft1, crossBottom1);
        graphics.drawLine(crossRight1, crossTop2, crossLeft2, crossBottom1);
        graphics.drawLine(crossRight2, crossTop1, crossLeft1, crossBottom2);
    
        graphics.setColor(col);
    
        if (extraIcon != null) {
          extraIcon.paintIcon(component, graphics, x + getWidth(), y + 2);
        }
      }
    
      @Override
      public int getIconWidth() {
        return getWidth() + (extraIcon != null ? extraIcon.getIconWidth() : 0);
      }
    
      @Override
      public int getIconHeight() {
        return getHeight();
      }
    
      /**
       * Returns the bounding rectangle of this icon.
       *
       * @return the bounding rectangle of this icon.
       * @see java.awt.Rectangle
       */
      public Rectangle getBounds() {
        return new Rectangle(getXPos(), getYPos(), getWidth(), getHeight());
      }
    
      /**
       * Returns the x-coordinate of the position of this icon.
       *
       * @return the x-coordinate of the position of this icon.
       */
      public int getXPos() {
        return xPos;
      }
    
      /**
       * Returns the y-coordinate of the position of this icon.
       *
       * @return the y-coordinate of the position of this icon.
       */
      public int getYPos() {
        return yPos;
      }
    
      /**
       * Returns the width of this icon.
       *
       * @return the width of this icon.
       */
      public int getWidth() {
        return width;
      }
    
      /**
       * Returns the height of this icon.
       *
       * @return the height of this icon.
       */
      public int getHeight() {
        return height;
      }
    
      /**
       * Returns the extra-icon, which is to be displayed next to this icon. Might be null.
       *
       * @return the extra-icon.
       */
      public Icon getExtraIcon() {
        return extraIcon;
      }
    
      /**
       * Sets the x-coordinate of the position of this icon.
       *
       * @param xPos the x-coordinate of the position of this icon.
       */
      protected void setXPos(int xPos) {
        this.xPos = xPos;
      }
    
      /**
       * Sets the y-coordinate of the position of this icon.
       *
       * @param yPos the y-coordinate of the position of this icon.
       */
      protected void setYPos(int yPos) {
        this.yPos = yPos;
      }
    
      /**
       * Sets the width of this icon.
       * <p>
       * This method should be called only within the constructor-methods.</p>
       *
       * @param width the width of this icon.
       */
      protected void setWidth(int width) {
        this.width = width;
      }
    
      /**
       * Sets the height of this icon.
       * <p>
       * This method should be called only within the constructor-methods.</p>
       *
       * @param height the height of this icon.
       */
      protected void setHeight(int height) {
        this.height = height;
      }
    
      /**
       * Sets the extra-icon to be displayed next to this icon.
       * <p>
       * This method should be called only within the constructor-methods.</p>
       *
       * @param extraIcon the extra icon to display.
       */
      protected void setExtraIcon(Icon extraIcon) {
        this.extraIcon = extraIcon;
      }
    }
    
    
    package de.dimensionv.java.gui.swing.panels;
    
    import java.awt.Component;
    import java.awt.Rectangle;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.Icon;
    import javax.swing.JTabbedPane;
    
    /**
     * A JTabbedPane that can have a close-icon ('X') on each tab.
     *
     * <p>
     * Since it is derived from JTabbedPane directly, it is used in exactly the same manner as the JTabbedPane. By default,
     * it even behaves equally, i.e. it does not add the close-icon, thus disabling the closing-capabilities completely for
     * a tab. To enable the closing-capabilities of a tab, add a boolean value (true) the the addTab-method-call.</p>
     *
     * <p>
     * To have an additional extra icon on each tab (e.g. showing the file type), use the method addTab(String, Component,
     * Icon) or addTab(String, Component, Icon, boolean). The first variant goes without closing-capabilities, while the
     * second, if the boolean is set to true, comes with closing-capabilities.</p>
     *
     * <p>
     * Clicking the 'X', of course, closes the tab. If you like to perform action, <b>after</b> the tab has already been
     * closed, implement an event-listener to capture the ComponentRemoved-event. The removed tab can be retrieved by
     * calling java.awt.event.ContainerEvent.getChild(), which is the event the listener will receive.</p>
     *
     * @author mjoellnir
     */
    public class CloseableTabbedPane extends JTabbedPane implements MouseListener {
    
      /**
       * Creates a new instance of ClosableTabbedPane
       */
      public CloseableTabbedPane() {
        super();
        initializeMouseListener();
      }
    
      /**
       * Appends a tab without closing-capabilities, just as the standard JTabbedPane would do.
       *
       * @see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
       */
      @Override
      public void addTab(String title, Component component) {
        this.addTab(title, component, null, false);
      }
    
      /**
       * Appends a tab with or without closing-capabilities, depending on the flag isClosable. If isClosable is true, a
       * close-icon ('X') is displayed left of the title.
       *
       * @param title Title of this tab.
       * @param component Contents of this tab.
       * @param isClosable en-/disable closing-capabilities
       * @see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
       */
      public void addTab(String title, Component component, boolean isClosable) {
        this.addTab(title, component, null, isClosable);
      }
    
      /**
       * Appends a tab with or without closing-capabilities, depending on the flag isClosable. If isClosable is true, a
       * close-icon ('X') is displayed left of the title. If extraIcon is not null, it will be displayed between the closing
       * icon (if present) and the tab's title. The extraIcon will be displayed indepently of the closing-icon.
       *
       * @param title Title of this tab.
       * @param component Contents of this tab.
       * @param extraIcon Extra icon to be displayed.
       * @param isClosable en-/disable closing-capabilities
       * @see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
       */
      public void addTab(String title, Component component, Icon extraIcon, boolean isClosable) {
        if (isClosable) {
          super.addTab(title, new CloseTabIcon(extraIcon), component);
        } else {
          if (extraIcon != null) {
            super.addTab(title, extraIcon, component);
          } else {
            super.addTab(title, component);
          }
        }
      }
    
      @Override
      public void mouseClicked(MouseEvent evt) {
        int tabIndex = getUI().tabForCoordinate(this, evt.getX(), evt.getY());
        if (tabIndex < 0) {
          return;
        }
    
        Icon icon = getIconAt(tabIndex);
    
        if ((icon == null) || !(icon instanceof CloseTabIcon)) {
          // This tab is not intended to be closeable.
          return;
        }
    
        Rectangle rect = ((CloseTabIcon) icon).getBounds();
        if (rect.contains(evt.getX(), evt.getY())) {
          //the tab is being closed
          this.removeTabAt(tabIndex);
        }
      }
    
      @Override
      public void mouseEntered(MouseEvent evt) {
      }
    
      @Override
      public void mouseExited(MouseEvent evt) {
      }
    
      @Override
      public void mousePressed(MouseEvent evt) {
      }
    
      @Override
      public void mouseReleased(MouseEvent evt) {
      }
    
      private void initializeMouseListener() {
        addMouseListener(this);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-05
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 2015-10-06
      • 2020-10-01
      相关资源
      最近更新 更多