2014-01-11 17 views
1

我一直在試圖讓我的JTextArea上的滾動條好幾天,我盡我所能地嘗試了各種方法。我正在創建一個聊天客戶端,並且使用空佈局的JPanel設置。我試過使用佈局管理器,但我不明白如何讓它看起來像我想要的樣子。如何在空佈局中添加滾動條?

我只是想在文本區域上滾動條。我是一個初學者,對於我讀過的東西,它不可能有一個空佈局?如果更容易,我願意幫助改變佈局。

Chat Server Client

package guiserver; 

import com.apple.eawt.Application; 
import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JPasswordField; 
import javax.swing.JScrollPane; 
import javax.swing.JSplitPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.SwingConstants; 
import javax.swing.WindowConstants; 

public class GUIserver extends JFrame implements ActionListener { 

JFrame login = new JFrame(); 
JPanel panel = new JPanel(); 
JPanel main = new JPanel(); 
JFrame accept = new JFrame(); 
JPanel acpt = new JPanel(); 
JPanel buttonpanel = new JPanel(); 
JButton acceptinvite = new JButton("Accept Invite"); 
JButton denyinvite = new JButton("Deny Invite"); 
JLabel acceptlabel = new JLabel(); 
JLabel acceptname = new JLabel(); 
JPanel loginpanel = new JPanel(); 
JTextArea chat = new JTextArea(" Waiting to Start Client..."); 
JSplitPane chatsplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 
JTextField input = new JTextField(); 
JScrollPane pane = new JScrollPane(chat); 
JButton send = new JButton("Send"); 
JLabel IP = new JLabel("IP:... "); 
JButton start = new JButton("Start"); 
sendThread s1 = new sendThread(); 
fromThread f1 = new fromThread(); 
infoFromThread f2 = new infoFromThread(); 
infoToThread s2 = new infoToThread(); 
RPSpickTimer pt = new RPSpickTimer(); 
myCanvas contact = new myCanvas(); 
myCanvas logo = new myCanvas(); 
JButton rock = new JButton("Rock"); 
JButton paper = new JButton("Paper"); 
JButton scissors = new JButton("Scissors"); 
JTextField username = new JTextField(); 
JLabel loguser = new JLabel("Username:"); 
JLabel logpass = new JLabel("Password:"); 
JPasswordField password = new JPasswordField(); 
JButton signin = new JButton("Sign in"); 
String inputText = "0"; 
String chatCurrent; 
String out1; 
String in; 
boolean pause = true; 
boolean rps = false; 
int P1pick = 0; 
int P2pick = 0; 
String user = "User 1"; 
String user2 = "Jacob Abthorpe"; 
String pass; 
int badge; 
int sendinvite = 0; 
char answerinvite = '-'; 
boolean pauseInfo = true; 
int winner = 0; 

public GUIserver() { 
    Application application = Application.getApplication(); 
    Image image = Toolkit.getDefaultToolkit().getImage("src/icon.png"); 
    application.setDockIconImage(image); 

    login.setVisible(true); 
    login.setSize(400, 500); 
    login.setLocationRelativeTo(null); 
    login.setTitle("Login"); 
    login.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    login.add(loginpanel); 
    loginpanel.setLayout(null); 
    loginpanel.add(username); 
    loginpanel.add(password); 
    loginpanel.add(signin); 
    loginpanel.add(logpass); 
    loginpanel.add(loguser); 
    loginpanel.add(logo); 
    login.setAlwaysOnTop(true); 
    username.setHorizontalAlignment(JTextField.CENTER); 
    password.setHorizontalAlignment(JTextField.CENTER); 
    username.setBounds(50, 290, 300, 30); 
    password.setBounds(50, 350, 300, 30); 
    loguser.setBounds(55, 265, 300, 30); 
    logpass.setBounds(55, 325, 300, 30); 
    signin.setBounds(150, 400, 100, 30); 
    logo.setBounds(110, 50, 150, 150); 
    username.addActionListener(this); 
    password.addActionListener(this); 
    signin.addActionListener(this); 

    setVisible(false); 
    setSize(500, 600); 
    setLocationRelativeTo(null); 
    setTitle("Chat Server Client"); 
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    setAlwaysOnTop(true); 
    panel.setLayout(null); 
    panel.setLocation(300, 0); 
    panel.add(pane); 
    panel.add(input); 
    panel.add(send); 
    panel.add(IP); 
    panel.add(start); 
    panel.add(rock); 
    panel.add(paper); 
    panel.add(scissors); 
    contact.picx = 120; 
    contact.picy = 120; 
    contact.setBackground(Color.white); 
    contact.setBounds(370, 10, 120, 120); 
    panel.add(contact); 
    input.addActionListener(this); 
    send.addActionListener(this); 
    start.addActionListener(this); 
    rock.addActionListener(this); 
    paper.addActionListener(this); 
    scissors.addActionListener(this); 
    chat.setEditable(false); 
    pane.setBounds(10, 10, 350, 450); 
    input.setEditable(false); 
    input.setBounds(10, 470, 350, 80); 
    start.setBounds(370, 470, 115, 80); 
    IP.setBounds(15, 520, 480, 80); 
    rock.setVisible(false); 
    paper.setVisible(false); 
    scissors.setVisible(false); 
    scissors.setBounds(370, 430, 115, 30); 
    paper.setBounds(370, 400, 115, 30); 
    rock.setBounds(370, 370, 115, 30); 
    setContentPane(panel); 


    accept.setVisible(false); 
    accept.setSize(400, 125); 
    accept.setLocationRelativeTo(null); 
    accept.setTitle("Rock, Paper, Scissors"); 
    accept.setAlwaysOnTop(true); 
    accept.setResizable(false); 
    accept.add(acpt); 
    acpt.setLayout(null); 
    acpt.add(acceptlabel); 
    acpt.add(buttonpanel); 
    acpt.add(acceptname); 
    buttonpanel.setBounds(0, 60, 400, 40); 
    buttonpanel.setLayout(new FlowLayout()); 
    acceptlabel.setHorizontalAlignment(SwingConstants.CENTER); 
    acceptlabel.setText("would like to play Rock, Paper, Scissors. Accept?"); 
    acceptlabel.setBounds(0, 25, 400, 40); 
    acceptname.setHorizontalAlignment(SwingConstants.CENTER); 
    acceptname.setText(user2 + ""); 
    acceptname.setBounds(0, 3, 400, 40); 
    buttonpanel.add(acceptinvite); 
    buttonpanel.add(denyinvite); 
    acceptinvite.addActionListener(this); 
    denyinvite.addActionListener(this); 
} 

public void actionPerformed(ActionEvent e) { 
    if (e.getSource() == input) { 
     if (input.getText().startsWith("/")) { 
      if (input.getText().contentEquals("/")) { 
       chat.append("\n\n >Type '/help' for list of all commands"); 
      } 
      if (input.getText().contentEquals("/start RPS")) { 
       chat.append("\n \n >Waiting for opponent to accept invite. . ."); 
       pauseInfo = false; 
       sendinvite = 10; 
      } 
      if (input.getText().contentEquals("/help")) { 
       chat.append("\n\n >Type '/help' for list of all commands"); 
       chat.append("\n >Type '/start RPS' to play Rock Paper Scissors"); 
       chat.append("\n >Type '/end' to quit current game"); 
      } 
      if (input.getText().contentEquals("/end")) { 
       if (rps == true) { 
        chat.append("\n\n >Quiting Rock, Paper, Scissors. . ."); 
        rps = false; 
        rock.setVisible(false); 
        paper.setVisible(false); 
        scissors.setVisible(false); 
       } 
      } 
      input.setText(""); 
     } else { 
      if ((input.getText().contentEquals("")) && (input.getText().contentEquals(" "))) { 
       Toolkit.getDefaultToolkit().beep(); 
      } else { 
       pause = false; 
       chat.append("\n \n " + user + " says: \n  " + input.getText()); 
       inputText = input.getText(); 
       input.setText(""); 
      } 
     } 
    } 
    if (e.getSource() == send) { 
     //chat.append("\n \n Dale Schmidt says: \n  " + inputText); 
     //pause = false; 
    } 
    if (e.getSource() == username) { 
     user = username.getText(); 
    } 
    if (e.getSource() == signin) { 
     login.setVisible(false); 
     setVisible(true); 
    } 
    if (e.getSource() == start) { 
     try { 
      s1.start(); 
      f1.start(); 
      s2.start(); 
      f2.start(); 
      setAlwaysOnTop(false); 
      chat.append("\n " + InetAddress.getLocalHost() + "\n Server started."); 
      IP.setText("IP: " + InetAddress.getLocalHost()); 
      start.setVisible(false); 
      send.setVisible(true); 
      input.setEditable(true); 
      send.setBounds(370, 470, 115, 80); 
     } catch (Exception s) { 
      System.out.print("YOLOerror starting server"); 
     } 
    } 
    if (e.getSource() == rock) { 
     if ((rps == true) && (P1pick == 0)) { 
      P1pick = 1; 
      chat.append("\n\n >You picked 'Rock'"); 
      if (P2pick != 0) { 
       pt.start(); 
      } 
     } 
    } 
    if (e.getSource() == paper) { 
     if ((rps == true) && (P1pick == 0)) { 
      P1pick = 2; 
      chat.append("\n\n >You picked 'Paper'"); 
      if (P2pick != 0) { 
       pt.start(); 
      } 
     } 
    } 
    if (e.getSource() == scissors) { 
     if ((rps == true) && (P1pick == 0)) { 
      P1pick = 3; 
      chat.append("\n\n >You picked 'Scissors'"); 
      if (P2pick != 0) { 
       pt.start(); 
      } 
     } 
    } 
    if (e.getSource() == acceptinvite) { 
     rps = true; 
     rock.setVisible(true); 
     paper.setVisible(true); 
     scissors.setVisible(true); 
     answerinvite = 'y'; 
     accept.dispose(); 
    } 
    if (e.getSource() == denyinvite) { 
     answerinvite = 'n'; 
     accept.dispose(); 
    } 
} 

class myCanvas extends Canvas { 

    int x = 10, y = 10; 
    int picx = 150, picy = 150; 

    public void paint(Graphics g) { 
     Image image1 = Toolkit.getDefaultToolkit().getImage("src/icon.png"); 
     g.drawImage(image1, x, y, picx, picy, this); 
    } 
}  

class sendThread extends Thread { 

    ServerSocket s1; 
    Socket sendclientSocket = null; 

    public void run() { 
     inputText = input.getText(); 
     try { 
      System.err.println("Starting Send Server"); 
      System.out.println(InetAddress.getLocalHost()); 
      s1 = new ServerSocket(4444); 
      sendclientSocket = s1.accept(); 
      System.err.println("Started Send Server"); 
     } catch (Exception s1) { 
      System.exit(1); 
     } 
     while (true) { 
      try { 
       PrintWriter out = new PrintWriter(sendclientSocket.getOutputStream(), true); 

       if (pause == false) { 
        badge = 0; 
        out.println(input.getText()); 
        System.out.println("sent"); 
        pause = true; 
       } 
      } catch (Exception e) { 
       System.err.println("Error Sending."); 
       System.err.println(e.getMessage()); 
       System.exit(2); 
      } 
     } 
    } 
} 

class fromThread extends Thread { 

    ServerSocket s2; 
    Socket fromclientSocket = null; 

    public void run() { 
     try { 
      System.err.println("Starting Recieve Server"); 
      s2 = new ServerSocket(4441); 
      fromclientSocket = s2.accept(); 
      System.err.println("Started Recieve Server"); 
     } catch (Exception s2) { 
      System.exit(1); 
     } 

     while (true) { 
      try { 

       BufferedReader in = new BufferedReader(new InputStreamReader(fromclientSocket.getInputStream())); 

       String fromClient = in.readLine(); 

       if (fromClient.contentEquals("")) { 

       } else {       
        Toolkit.getDefaultToolkit().beep(); 
        chat.append("\n\n " + user2 + " says:\n  " + fromClient); 
        badge++; 
        Application.getApplication().setDockIconBadge(Integer.toString(badge)); 
       } 

      } catch (Exception e) { 
       System.err.println("Error Receiving."); 
       System.err.println(e.getMessage()); 
       System.exit(3); 
      } 
     } 
    } 
} 

class infoFromThread extends Thread { 

    ServerSocket s3; 
    Socket infoFromClientSocket = null; 

    public void run() { 
     try { 
      s3 = new ServerSocket(4446); 
      infoFromClientSocket = s3.accept(); 
     } catch (Exception s3) { 
      System.exit(7); 
     } 

     while (true) { 
      try { 

       BufferedReader in = new BufferedReader(new InputStreamReader(infoFromClientSocket.getInputStream())); 

       String infoFromClient = in.readLine(); 

       if (infoFromClient.contentEquals("10")) { 
        accept.setVisible(true); 
        sendinvite = 0; 
       } else if (infoFromClient.contentEquals("y")) { 
        chat.append("\n >Invite Accepted"); 
        rps = true; 
        rock.setVisible(true); 
        paper.setVisible(true); 
        scissors.setVisible(true); 
        answerinvite = '-'; 
       } else if (infoFromClient.contentEquals("n")) { 
        chat.append("\n\n >Invite Declined"); 
        answerinvite = '-'; 
       } else if (infoFromClient.contentEquals("1")) { 
        chat.append("\n\n >Opponent made selection"); 
        P2pick = 1; 
        if (P1pick != 0) { 
         pt.start(); 
        } 
       } else if (infoFromClient.contentEquals("2")) { 
        chat.append("\n\n >Opponent made selection"); 
        P2pick = 2; 
        if (P1pick != 0) { 
         pt.start(); 
        } 
       } else if (infoFromClient.contentEquals("3")) { 
        chat.append("\n\n >Opponent made selection"); 
        P2pick = 3; 
        if (P1pick != 0) { 
         pt.start(); 
        } 
       } 

      } catch (Exception e) { 
       System.err.println("Error Receiving Information."); 
       System.err.println(e.getMessage()); 
       System.exit(3); 
      } 
     } 
    } 
} 

class infoToThread extends Thread { 

    ServerSocket s4; 
    Socket infoToClientSocket = null; 

    public void run() { 
     inputText = input.getText(); 
     try { 
      s4 = new ServerSocket(4447); 
      infoToClientSocket = s4.accept(); 
     } catch (Exception s4) { 
      System.exit(8); 
     } 
     while (true) { 
      try { 
       PrintWriter out = new PrintWriter(infoToClientSocket.getOutputStream(), true); 

       if (sendinvite == 10) { 
        out.println(sendinvite); 
        sendinvite = 0; 
        pauseInfo = false; 
       } 
       if ((answerinvite == 'y') || (answerinvite == 'n')) { 
        out.println(answerinvite); 
        answerinvite = '-'; 
       } 

        if (winner == 1) { 
         out.println("Loser"); 
        } 
        else if (winner == 2) { 
         out.println("Winner"); 
        } 
        else if (winner == 3) { 
         out.println("Tie"); 
        } 
        //winner = 0; 

       //System.err.println("infoToClient"); 
      } catch (Exception e) { 
       System.err.println("Error Sending Information."); 
       System.err.println(e.getMessage()); 
       System.exit(2); 
      } 
     } 
    } 
} 
class RPSpickTimer extends Thread { 

    public void run() { 
     while (true) { 
      try { 
       if (P1pick != 0) { 
       if (P1pick == 1) { 
        if (P2pick == 1) { 
         //tie 
         chat.append("\n\n Tie!"); 
         winner = 3; 
        } else if (P2pick == 2) { 
         //P2wins 
         chat.append("\n\n " + user2 + " wins!"); 
         winner = 2; 
        } else if (P2pick == 3) { 
         //P1wins 
         chat.append("\n\n " + user + " wins!"); 
         winner = 1; 
        } 

       } else if (P1pick == 2) { 
        if (P2pick == 1) { 
         //P1wins 
         chat.append("\n\n " + user + " wins!"); 
         winner = 1; 
        } else if (P2pick == 2) { 
         //tie 
         chat.append("\n\n Tie!"); 
         winner = 3; 
        } else if (P2pick == 3) { 
         //P2wins 
         chat.append("\n\n " + user2 + " wins!"); 
         winner = 2; 
        } 

       } else if (P1pick == 3) { 
        if (P2pick == 1) { 
         //P2wins 
         chat.append("\n\n " + user2 + " wins!"); 
         winner = 2; 
        } else if (P2pick == 2) { 
         //P1wins 
         chat.append("\n\n " + user + " wins!"); 
         winner = 1; 
        } else if (P2pick == 3) { 
         //tie 
         chat.append("\n\n Tie!"); 
         winner = 3; 
        } 
       } 
       P1pick = 0; 
       P2pick = 0; 
      } 
      else { 
       sleep(250); 
      } 

      } catch (Exception e) { 
       System.err.println("Error Picking Winner."); 
       System.err.println(e.getMessage()); 
       System.exit(2); 
      } 
     } 
    } 
} 

public static void main(String[] args) { 
    GUIserver s = new GUIserver(); 

}` 
+2

一般建議不要使用空佈局。 Swing圍繞佈局管理器的概念而設計 – MadProgrammer

+0

垂直對齊在哪裏! – Tdorno

+1

而不是null佈局使用其他佈局,其他佈局爲您提供更多facilities.May這可以幫助您http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane。html –

回答

2

這條線:

panel.add(chat); 

而不是增加chat,加pane,如:

panel.add(pane); 
+1

呃!謝謝,我已經試過,但確實改變了setBounds以匹配窗格。所以當我運行這個程序時,它將是空白的。 – Dale

2

JTextArea文檔「的java.awt.TextArea中內部處理滾動。JTextArea不同因爲它不管理滾動,但實現了Scrollable接口。這允許它被放置在JScrollPane的內部,如果滾動行爲期望,如果滾動不希望直接使用「

我認爲這意味着這是你想要的東西:

JTextArea chat = new JTextArea(" Waiting to Start Client..."); 
JScrollPane chatScrollPane = new JScrollPane(chat); 

... 

panel.setLocation(300, 0); 
panel.add(chatScrollPane); 
panel.add(input); 

由於尼古拉斯卡羅指出,你已經有了JScrollPane,只需要添加它,而不是JTextArea。基本上,Java UI系統(和大多數UI系統)是一個巨大的小部件樹,如果你不添加一個小部件到樹中,沒有效果,在這種情況下,JScrollPane沒有被添加到樹中,因此沒有爲你做任何事情。

+1

我知道它很難閱讀代碼,但他有一個jscrollpane,他只是再次添加jtextarea,而不是將他的jscrollpane添加到面板。 +1供參考。 –

+0

啊,很好。 – CrazyCasta

2

這不是一個答案,但一個LayoutManager如何可能被用來實現OP的結果的示範

所以,根據你的代碼示例中,我得到這個輸出...

BadLayout

希望大家注意的是,框架是不是大到足以容納的內容,這是null佈局的主要問題,他們從來不看在其他系統一樣...

並利用一個GridBagLayoutGridLayout並稱爲「複合佈局」的一個概念,我可以嘲笑這個...

BetterLayout

import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.Insets; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ChatLayout { 

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

    public ChatLayout() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new ChatPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class ChatPane extends JPanel { 

     private JTextArea chatWindow; 
     private JTextField input; 
     private JLabel ipLabel; 

     private JButton rockBtn; 
     private JButton paperBtn; 
     private JButton scissorsBtn; 
     private JButton startBtn; 

     public ChatPane() { 

      JPanel leftPane = new JPanel(new GridBagLayout()); 
      JPanel rightPane = new JPanel(new GridBagLayout()); 

      chatWindow = new JTextArea(20, 40); 
      chatWindow.setText("Waiting to start chat..."); 

      input = new JTextField(10); 
      ipLabel = new JLabel("IP..."); 

      rockBtn = new JButton("Rock"); 
      paperBtn = new JButton("Paper"); 
      scissorsBtn = new JButton("Scissors"); 
      startBtn = new JButton("Start"); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.insets = new Insets(4, 4, 4, 4); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.fill = GridBagConstraints.BOTH; 
      gbc.weighty = 1; 
      gbc.weightx = 1; 
      leftPane.add(new JScrollPane(chatWindow), gbc); 

      gbc.gridy++; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.weighty = 0; 
      gbc.weightx = 1; 
      gbc.gridheight = 1; 
      leftPane.add(input, gbc); 

      gbc.gridy++; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      leftPane.add(ipLabel, gbc); 

      JPanel buttonsPane = new JPanel(new GridLayout(3, 1)); 
      buttonsPane.add(rockBtn); 
      buttonsPane.add(paperBtn); 
      buttonsPane.add(scissorsBtn); 

      gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.anchor = GridBagConstraints.SOUTH; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.weighty = 1;    
      rightPane.add(buttonsPane, gbc); 

      gbc.gridy++; 
      gbc.insets = new Insets(8, 0, 0, 0); 
      gbc.fill = GridBagConstraints.BOTH; 
      gbc.anchor = GridBagConstraints.CENTER; 
      gbc.weighty = 0; 
      gbc.gridheight = 2; 
      gbc.ipadx = 30; 
      gbc.ipady = 30; 
      rightPane.add(startBtn, gbc); 

      gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.weightx = 1; 
      gbc.weighty = 1; 
      gbc.fill = GridBagConstraints.BOTH; 
      add(leftPane, gbc); 

      gbc.gridx++; 
      gbc.weightx = 0; 
      gbc.weighty = 1; 
      add(rightPane, gbc); 
     } 

    } 

} 

現在,這只是一個例子。您需要的可能會有所不同,這將需要使用不同的佈局管理器或使用不同的佈局管理器...

+0

我複製了你的代碼並做了一個測試項目..我得到這個錯誤「在源碼1.6 (使用-source 7或更高版本來啓用多catch語句)中不支持多catch語句」「在UIManager中嘗試並捕獲。 – Dale

+0

您有兩種選擇,使用Java 7(設置您的IDE以使用Java 7進行編譯並使用Java 7源代碼兼容性),或者用傳統的多步'catch'代替'catch'語句。 – MadProgrammer

+2

@MadProgrammer您忘記了第三個選項。 '趕上(例外)'。雖然這對於生產代碼來說並不理想,但它對於MCVE來說很好。 –