String wb; // 成員變數
else if (e.getActionCommand().equals("查找")) {
wb = wby.getText(); // 賦值給成員變數
new Way(1); // 開啟對話框
}
else if (e.getActionCommand().equals("開始")) {
System.out.print(wb); // 此處 wb 為 null!
int s = wb.indexOf(...); // NPE
}
**區域變數遮蔽**:在 `"查找"` 分支中,**重新宣告**了 `String wb = wby.getText();` (或類似),導致賦值給**區域變數**,而非成員變數。成員變數 `wb` 保持 `null`,後續 `"開始"` 分支讀取成員變數 → NPE。
// 移除區域宣告,直接賦值給成員變數
else if (e.getActionCommand().equals("查找")) {
this.wb = wby.getText(); // 明確 this.wb
new Way(1);
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FindTextDemo extends JFrame {
private JTextArea textArea;
private JTextField findField;
private String lastFindText = ""; // 成員變數保存搜尋關鍵字
private int searchIndex = 0;
public FindTextDemo() {
setTitle("文字搜尋示例");
setSize(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel top = new JPanel(new BorderLayout());
top.add(new JLabel("搜尋:"), BorderLayout.WEST);
findField = new JTextField(15);
top.add(findField, BorderLayout.CENTER);
JButton btnFind = new JButton("查找");
JButton btnNext = new JButton("下一個");
top.add(btnFind, BorderLayout.EAST);
add(top, BorderLayout.NORTH);
textArea = new JTextArea();
textArea.setText("白日依山盡,\n黃河入海流;\n欲窮千里目,\n更上一層樓");
add(new JScrollPane(textArea), BorderLayout.CENTER);
btnFind.addActionListener(e -> {
lastFindText = findField.getText(); // 賦值給成員變數
searchIndex = 0;
findNext();
});
btnNext.addActionListener(e -> findNext());
}
private void findNext() {
if (lastFindText.isEmpty()) return;
String content = textArea.getText();
int pos = content.indexOf(lastFindText, searchIndex);
if (pos >= 0) {
textArea.setCaretPosition(pos);
textArea.moveCaretPosition(pos + lastFindText.length());
searchIndex = pos + 1;
} else {
JOptionPane.showMessageDialog(this, "搜尋完畢");
searchIndex = 0;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new FindTextDemo().setVisible(true));
}
}