Java tutorial
/* * Copyright (C) 2009 Nicolas Dutertry * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.glimpse.client.news; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.glimpse.client.Aggregator; import org.glimpse.client.ClientUtils; import org.glimpse.client.Component; import org.glimpse.client.i18n.AggregatorConstants; import org.glimpse.client.layout.ComponentDescription.Type; import org.glimpse.client.widgets.HorizontalPanelExt; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.URL; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; public class NewsReader extends Component { private static final String PROPERTY_URL = "url"; private static final String PROPERTY_DIRECT_OPEN = "directOpen"; private static final String PROPERTY_MAX_PER_PAGE = "maxPerPage"; private static final int MAX_VISITED_ENTRIES = 30; static NewsRetrieverServiceAsync newsRetrieverService = GWT.create(NewsRetrieverService.class); private AggregatorConstants constants = GWT.create(AggregatorConstants.class); private Anchor title = new Anchor(constants.newsReader()); private Image titleImage; private HorizontalPanel loadingPanel = new HorizontalPanel(); private SimplePanel optionPanel; private TextBox urlField; private CheckBox directOpenBox; private ListBox maxBox; // Le tableau des news private EntriesTable entriesTable; Anchor previousButton = new Anchor(); Anchor nextButton = new Anchor(); private Label error; private boolean initialized; private List<String> visitedEntries; private class RefreshHandler implements ClickHandler { public void onClick(ClickEvent event) { refresh(true); } } private class OptionHandler implements ClickHandler { public void onClick(ClickEvent event) { if (optionPanel.isVisible()) { optionPanel.setVisible(false); } else { synchronizeOptions(); optionPanel.setVisible(true); } } } private class NextHandler implements ClickHandler { public void onClick(ClickEvent event) { entriesTable.nextPage(); checkPreviousNext(); } } private class PreviousHandler implements ClickHandler { public void onClick(ClickEvent event) { entriesTable.previousPage(); checkPreviousNext(); } } public NewsReader() { this(new HashMap<String, String>()); } public NewsReader(Map<String, String> properties) { super(properties); visitedEntries = ClientUtils.stringToList(getProperty("visitedEntries")); entriesTable = new EntriesTable(this); // Les boutons de commande du titre HorizontalPanel titlePanel = new HorizontalPanel(); titlePanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); titleImage = new Image("images/feed.png"); titleImage.setStylePrimaryName("component-title-image"); titlePanel.add(titleImage); title.setHref("javascript:void(0)"); title.setTarget("_blank"); titlePanel.add(title); setTitleWidget(titlePanel); List<Widget> actions = new LinkedList<Widget>(); FocusPanel refreshButton = new FocusPanel(new Image(Aggregator.TRANSPARENT_IMAGE)); refreshButton.setTitle(constants.refresh()); refreshButton.setStylePrimaryName("component-action-refresh"); refreshButton.addClickHandler(new RefreshHandler()); actions.add(refreshButton); if (Aggregator.getInstance().isModifiable()) { FocusPanel optionButton = new FocusPanel(new Image(Aggregator.TRANSPARENT_IMAGE)); optionButton.addClickHandler(new OptionHandler()); optionButton.setTitle(constants.options()); optionButton.setStylePrimaryName("component-action-options"); actions.add(optionButton); } setActions(actions); // Contenu VerticalPanel panel = new VerticalPanel(); panel.setWidth("100%"); optionPanel = new SimplePanel(); optionPanel.setStylePrimaryName("component-options"); VerticalPanel vp = new VerticalPanel(); FlexTable table = new FlexTable(); table.setText(0, 0, constants.url()); urlField = new TextBox(); table.setWidget(0, 1, urlField); table.setText(1, 0, constants.directOpen()); directOpenBox = new CheckBox(); table.setWidget(1, 1, directOpenBox); table.setText(2, 0, constants.maxEntries()); maxBox = new ListBox(); for (int i = 1; i <= 20; i++) { maxBox.addItem(String.valueOf(i)); } table.setWidget(2, 1, maxBox); vp.add(table); synchronizeOptions(); Button button = new Button(constants.ok()); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { setProperty(PROPERTY_URL, urlField.getValue()); setProperty(PROPERTY_DIRECT_OPEN, Boolean.toString(directOpenBox.getValue())); setProperty(PROPERTY_MAX_PER_PAGE, Integer.toString(maxBox.getSelectedIndex() + 1)); Aggregator.getInstance().update(); refresh(); } }); vp.add(button); optionPanel.add(vp); panel.add(optionPanel); // Le tableau des news panel.add(entriesTable); // image de chargement Image wait = new Image("wait.gif"); loadingPanel.add(wait); loadingPanel.setWidth("100%"); loadingPanel.setVisible(false); loadingPanel.setCellHorizontalAlignment(wait, HorizontalPanel.ALIGN_CENTER); panel.add(loadingPanel); // En cas d'erreur error = new Label(constants.error()); error.setVisible(false); panel.add(error); // Les boutons de commande du bas HorizontalPanelExt bottomBar = new HorizontalPanelExt(); bottomBar.setWidth("100%"); previousButton.setText(constants.previous()); previousButton.setHref("javascript:void(0)"); previousButton.setStylePrimaryName("news-previous"); previousButton.addClickHandler(new PreviousHandler()); bottomBar.add(previousButton); bottomBar.setCellHorizontalAlignment(previousButton, HorizontalPanel.ALIGN_LEFT); nextButton.setText(constants.next()); nextButton.setHref("javascript:void(0)"); nextButton.setStylePrimaryName("news-next"); nextButton.addClickHandler(new NextHandler()); bottomBar.add(nextButton); bottomBar.setCellHorizontalAlignment(nextButton, HorizontalPanel.ALIGN_RIGHT); panel.add(bottomBar); setContent(panel); checkPreviousNext(); } public void refresh() { refresh(false); } public void refresh(boolean serverRefresh) { initialized = true; final String url = getUrl(); entriesTable.clear(); if (url == null || url.trim().equals("")) { optionPanel.setVisible(true); checkPreviousNext(); return; } else { optionPanel.setVisible(false); } error.setVisible(false); loadingPanel.setVisible(true); checkPreviousNext(); newsRetrieverService.getNewsChannel(url, serverRefresh, new AsyncCallback<NewsChannel>() { public void onFailure(Throwable caught) { loadingPanel.setVisible(false); error.setVisible(true); } public void onSuccess(NewsChannel channel) { loadingPanel.setVisible(false); if (channel != null) { String channelTitle = channel.getTitle(); if (channelTitle.length() > 60) { channelTitle = channelTitle.substring(0, 60) + "..."; } title.setText(channelTitle); title.setHref(channel.getUrl()); String encodedUrl = URL.encodeQueryString(channel.getUrl()); titleImage.setUrl("servlets/news-icon?url=" + encodedUrl); entriesTable.setProperties(channel.getEntries(), getUrl(), getMaxPerPage(), isDirectOpen()); checkPreviousNext(); } else { error.setVisible(true); } } }); } public void checkPreviousNext() { if (entriesTable.hasPreviousPage()) { previousButton.setVisible(true); } else { previousButton.setVisible(false); } if (entriesTable.hasNextPage()) { nextButton.setVisible(true); } else { nextButton.setVisible(false); } } public String getUrl() { return getProperty(PROPERTY_URL); } public boolean isDirectOpen() { return !"false".equals(getProperty(PROPERTY_DIRECT_OPEN)); } public int getMaxPerPage() { String s = getProperty(PROPERTY_MAX_PER_PAGE); if (s == null || s.equals("")) { return 10; } else { return Integer.valueOf(s); } } private void synchronizeOptions() { urlField.setValue(getUrl()); directOpenBox.setValue(isDirectOpen()); maxBox.setSelectedIndex(getMaxPerPage() - 1); } @Override public Type getType() { return Type.NEWS; } @Override protected void onTabActivated() { super.onTabActivated(); if (!initialized) { refresh(); } } public boolean isVisited(String entryId) { return visitedEntries.contains(entryId); } public void addVisitedEntry(String entryId) { visitedEntries.add(entryId); while (visitedEntries.size() > MAX_VISITED_ENTRIES) { visitedEntries.remove(0); } setProperty("visitedEntries", listToString(visitedEntries)); Aggregator.getInstance().update(); } private static String listToString(List<?> list) { if (list == null) { return ""; } StringBuilder s = new StringBuilder(); for (Object o : list) { if (s.length() > 0) { s.append(","); } s.append(o.toString()); } return s.toString(); } }