MVC アーキテクチャのバージョンを使用してプログラムを作成しました。このコードの目的は、Web ページのリストの h1 タイトルをスクレイピングし、結果を JTable に返すことです。
これまでのところ、プログラムは正常に動作しています。私が望むように結果を返していますが、最後までテーブルを更新しません。結果が出たらテーブルを更新したいのですが、学習しているだけなので、ベストプラクティスの原則を考慮した方法でこれを行いたいと思っています。
必要に応じてこれを更新すると思いますが、コードを少し変更する必要があります。GUI を動的に更新する最善の方法がわかりません (スレッド、オブザーバー、その他の何か?)。「このコードを MVC パターンのどこに置くべきか?」という質問があるかどうかさえわかりません。理にかなっていますか?
とにかくここに私の見解があります:
public class SearchView extends JFrame{
//Components
private JLabel selectElementLabel = new JLabel("Element Selector:");
private JTextField selectElement = new JTextField("h1");;
private JComboBox<String> selectLocale;
private DefaultTableModel tableModel = new DefaultTableModel();
private JTable resultTable = new JTable(tableModel);
private JLabel statusLabel;
private JButton runButton = new JButton("Run");
private JButton clearButton = new JButton("Clear");
private SearchModel s_model;
//Constructor
public SearchView(SearchModel model) {
//Set the Logic here(model)
s_model = model;
//Initialise Components here(model)
selectLocale = new JComboBox<>(s_model.getLocales());
selectLocale.setSelectedIndex(13);
//Layout Components
JPanel userInputPanel = new JPanel();
userInputPanel.setLayout(new BoxLayout(userInputPanel, BoxLayout.X_AXIS));
userInputPanel.add(selectElementLabel);
userInputPanel.add(selectElement);
userInputPanel.add(selectLocale);
tableModel.addColumn("Page");
tableModel.addColumn("Data");
resultTable.setFillsViewportHeight(true);
JScrollPane resultScroller = new JScrollPane(resultTable);
resultScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
resultScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
resultScroller.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel controlButtons = new JPanel();
controlButtons.setLayout(new FlowLayout(FlowLayout.RIGHT));
controlButtons.add(statusLabel = new JLabel(s_model.getState()));
controlButtons.add(clearButton);
controlButtons.add(runButton);
this.setTitle("Element Searcher");
this.add(BorderLayout.NORTH, userInputPanel);
this.add(BorderLayout.CENTER, resultScroller);
this.add(BorderLayout.SOUTH, controlButtons);
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setMinimumSize(new Dimension(900, 600));
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void reset(){
tableModel.setRowCount(0);
}
String getSelectedElement(){
return selectElement.getText();
}
String getSelectedLocale(){
return selectLocale.getSelectedItem().toString();
}
void setResults(Object[] result){
tableModel.addRow(result);
}
void addRunListener(ActionListener run){
runButton.addActionListener(run);
}
void addClearListerner(ActionListener clear){
clearButton.addActionListener(clear);
}
}
コントローラ:
public class SearchController {
private SearchModel s_model;
private SearchView s_view;
public SearchController(SearchModel model, SearchView view) {
s_model = model;
s_view = view;
s_view.addRunListener(new RunListener());
s_view.addClearListerner(new ClearListener());
}
class RunListener implements ActionListener{
public void actionPerformed(ActionEvent e){
String selectedLocale = null;
try {
selectedLocale = s_view.getSelectedLocale();
s_model.setPageList(selectedLocale);
for (String pageUrl : s_model.getPageList()){
s_view.setResults(s_model.getResults(pageUrl));
}
} catch (Exception e1) {
System.out.println(e1);
}
}
}
class ClearListener implements ActionListener{
public void actionPerformed(ActionEvent e){
s_model.reset();
s_view.reset();
}
}
}
そして最後に私のモデル:
public class SearchModel {
//Constants
private static final String[] localeStrings = { "cs-cz", "da-dk", "de-at", "de-ch", "de-de", "el-gr", "en-ae", "en-au", "en-ca", "en-gb", "en-ie", "en-in", "en-nz", "en-us", "en-za", "es-cl", "es-co", "es-es", "es-mx", "fi-fi", "fr-be", "fr-ca", "fr-ch", "fr-fr", "hu-hu", "it-it", "ja-jp", "ko-kr", "nb-no", "nl-be", "nl-nl", "pl-pl", "pt-br", "pt-pt", "ru-ru", "sk-sk", "sv-se", "zh-hk", "zh-sg", "zh-tw" };
private static final String INITIAL_STATE = "idle";
private HashSet<String> pageList;
private Object[] scrapeResult;
private String locale = "en-us";
//Search State
private String searchState;
public SearchModel() {
reset();
}
public void setPageList(String loc){
locale = loc;
ScrapeXML scraper = new ScrapeXML(locale);
pageList = scraper.getUrls();
}
public void setResults(String page){
ScrapeElements scraper = new ScrapeElements(page, locale);
scrapeResult = scraper.getResults();
}
public void reset(){
searchState = INITIAL_STATE;
}
public String[] getLocales(){
return localeStrings;
}
public String getState(){
return searchState;
}
public HashSet<String> getPageList(){
return pageList;
}
public Object[] getResults(String page){
setResults(page);
return scrapeResult;
}
}
コード自体に関するコメントや提案があれば、お知らせください。
ありがとう!