I developed RssFeed Application using LWUIT j2me(java) for 2 xml files, now I want to show those 2 xml files on LWUIT Tabs.
That means, when my application runs, default tab will be displayed (on that tab my first Rss xml file Titles should be displayed), and when the user click on tab2 my second Rss xml titles should be displayed.
I am able to display the same titles of one rss files on both the tabs, how to control my flow to achieve my task?
Here my code:
public class XMLMidlet extends MIDlet implements ActionListener {
public XMLMidlet() {
Display.init(this);
news = new Vector();
m_backCommand = new Command("Back");
cmdExit = new Command("EXIT");
cmdDetails = new Command("Details");
}
public void startApp() {
//RssFeed URL's
String urls[] = {"http://topnews-23.rss",
"http://topstory-12.rss"};
for(int i=0;i<urls.length;i++){
ParseThread myThread = new ParseThread(this,urls[i]);
//this will start the second thread
myThread.getXMLFeed(urls[i]);
}
}
//method called by the parsing thread
public void addNews(News newsItem,String url) {
try{
news.addElement(newsItem);
form1 = new Form();
myNewsList = new List(newsVector);
newsList =new List(newsVector);
myNewsList.setRenderer(new NewsListCellRenderer());
newsList.setRenderer(new NewsListCellRenderer());
tabs=new Tabs(Component.TOP);
tabs.addTab("TopNews", myNewsList);
tabs.addTab("Topstory",newsList);
form1.addComponent(tabs);
form1.show();
}
catch(Exception e){
e.printStackTrace();
}
}
You should move below code
myNewsList = new List(newsVector);
newsList =new List(newsVector);
myNewsList.setRenderer(new NewsListCellRenderer());
newsList.setRenderer(new NewsListCellRenderer());
tabs=new Tabs(Component.TOP);
form1 = new Form();
tabs=new Tabs(Component.TOP);
tabs.addTab("TopNews", myNewsList);
tabs.addTab("Topstory",newsList);
from addNews method to constructor XMLMidlet. addNews method should use url parameter to differ for which list the newsItem is directed.
Update
Below is how I think you should implement addNews method:
public void addNews(News newsItem, String url) {
if (url.endsWith("topnews-20.rss")) {
myNewsList.addElement(newsItem);
} else if (url.endsWith("topstory-25.rss")) {
newsList.addElement(newsItem);
}
}
serRenderer does not need to be called from addNews and form1.show() should be moved to startApp.
Related
My app is a list of element names. Clicking one goes to another activity with more details, and an editText and button to change its name. When I go back to the list, I want it to have the new name if updated. My onCreate method has this code which populates it from the database perfectly (ignore the hardcoded size, its just simpler for debugging)
final String DATABASE_NAME = "element_db";
final AppDatabase appDatabase;
appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, DATABASE_NAME).build();
ListView list = (ListView)findViewById(R.id.listView);
final String[] element = new String[3];
new Thread(new Runnable() {
#Override
public void run() {
List<Element> elements;
elements = appDatabase.elementDao().fetchElements(); // a dao query "select*from"
int size = elements.size();
for (int i = 0; i < size; i++){
element[i] = elements.get(i).getName();
}
}
}) .start();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.activity_list_view, R.id.textView, element);
list.setAdapter(arrayAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MainActivity.this, itemdetail.class);
i.putExtra("pos", position);
startActivity(i);
}
});
To achieve an updated list when returning to this screen, I copied the above code into the onRestart method, but now the database does not return anything. If I just set the array that goes into the adapter to {"a", "a", "a"} the list populates fine. Any ideas why the database works onCreate but not onRestart?
I think you can use ViewModel and livedata to observe any database change
i have a simple JavaFx browser that is launched through a JButton that it's placed into a JFrame. Now, i wanted to put the JavaFx broser into a separate thread that should run even if the JFrame is closed. Now, if i close the JFrame with that JButton, the JavaFx browser also closes. I've tried multiple combinations, done research over internet, but with no success. Hope you guys can help me with a little example. Thanks !
browser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == browser) {
// create a JFXPanel, which will start the FX toolkit
// if it's not already started: - folosit pt a integra componente de tip FX Stage in componente swing (mai vechi) (JFrame)
JFXPanel fxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
#Override
public void run() {
Scene scene;
TextField addressField;
WebView webView;
WebEngine webEngine;
Stage stage = null;
Button reloadButton, goButton, backButton , forwardButton, historyList;
HBox hBox = new HBox(5);
hBox.setAlignment(Pos.CENTER);
//The TextField for entering web addresses.
addressField = new TextField("Ionutz says: Enter the address here....");
addressField.setPrefColumnCount(50); //make the field at least 50 columns wide.
//Add all out navigation nodes to the vbox.
reloadButton = new Button("Reload page");
goButton = new Button("Search");
backButton = new Button("Back");
forwardButton = new Button("Forward");
historyList = new Button("History");
String urlSearch = "http://icons.iconarchive.com/icons/ampeross/qetto-2/24/search-icon.png";
String urlReload = "http://icons.iconarchive.com/icons/graphicloads/colorful-long-shadow/24/Arrow-reload-2-icon.png";
String URLBack = "http://icons.iconarchive.com/icons/custom-icon-design/flatastic-1/24/back-icon.png";
String URLForward = "http://icons.iconarchive.com/icons/custom-icon-design/flatastic-1/24/forward-icon.png";
String URLHistory = "http://icons.iconarchive.com/icons/delacro/id/24/History-icon.png";
goButton.setGraphic(new ImageView(urlSearch));
reloadButton.setGraphic(new ImageView(urlReload));
forwardButton.setGraphic(new ImageView(URLForward));
backButton.setGraphic(new ImageView(URLBack));
historyList.setGraphic(new ImageView(URLHistory));
hBox.getChildren().addAll(backButton, forwardButton, addressField, reloadButton, goButton, historyList);
//Our weiv that display ther page.
webView = new WebView();
//the engine that manages our pages.
webEngine = webView.getEngine();
webEngine.setJavaScriptEnabled(true);
webEngine.load("http://www.google.ro");
//our main app layout with 5 regions.
BorderPane root = new BorderPane();
root.setPrefSize(1280, 720);
//Add every node to the BorderPane.
root.setTop(hBox);
root.setCenter(webView);
//Our scene is where all the action in JavaFX happens. A scene holds all Nodes, and its root node is our BorderPane.
scene = new Scene(root);
//the stage manages the scene.
fxPanel.setScene(scene);
JFrame browserFrame = new JFrame();
browserFrame.add(fxPanel);
browserFrame.setTitle("Ionutz Asaftei Browser");
browserFrame.setBounds(200, 200, 1280, 720);
browserFrame.setVisible(true);
// adaugam event handlers !!!! - cele mai simple pt Buttons
reloadButton.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
public void handle(javafx.event.ActionEvent event) {
webEngine.reload();
}
});
goButton.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
public void handle(javafx.event.ActionEvent event) {
webEngine.load("http://"+addressField.getText());
}
});
forwardButton.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
public void handle(javafx.event.ActionEvent event) {
webEngine.getHistory().go(1); //avanseaza cu o pagina in functie de intrarile din history
}
});
backButton.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
public void handle(javafx.event.ActionEvent ev) {
webEngine.getHistory().go(-1); //merge in urma cu o pagina in functie de intrarile din history
}
});
}
});
}
}
});
The JavaFX toolkit is single threaded from a user application point of view. It is not possible to spawn multiple threads launching WebView instances.
my web application offers a download. Javascript creats at the click the url (it depends on the user input) and the browser should open it, so that the page isn't reloaded.
For that, I think I have to alternatives:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
Both works under Firefox. Problem with open new window method: If the creation of the file at the server needs more time, the new empty tab will be closed late.
Problem with iframe: If there is an error at the server, no feedback is given.
I think at firefox the iframe is the better solution. But the web application must run with an JavaFX WebView, too. JavaFX haven't a download feature, I have to write it. One possible way is to listen on the location property:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
There are some problems:
The download start depends on a part of the url, because JafaFX supports no access to the http headers (that is bearable)
If the user starts the download with the same url two times, only the first download works (the change event only fires, if the url is new). I can crate unique urls (with #1, #2 and so on at the end). But this is ugly.
Only the "window.open(pathToFile);" method works. Loading an iframe don't fire the change location event of the website. That is expectable but I haven't found the right Listener.
Can someone help me to solve 2. or 3.?
Thank you!
PS: Sorry for my bad english.
edit:
For 2. I found a way. I don't know if it is a good one, if it is performant, if the new webview is deleted or is in the cache after download, ....
And the user don't get an feedback, when some a problem is raised:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
#Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}
I think you may just need to use copyURLtoFile to get the file...call that when the location changes or just call that using a registered java class. Something like this:
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
Using copyURLToFile the current page doesn't have to serve the file. I think registering the class is probably the easiest way to go... something like this:
PHP Code:
Download $filename
Java (in-line class in your javafx class/window... in this case my javafx window is inside of a jframe):
public class JavaApp {
JFrame cloudFrameREF;
JavaApp(JFrame cloudFrameREF)
{
this.cloudFrameREF = cloudFrameREF;
}
public void getfile(String filename) {
String newLoc = "http://your_web_site.com/send_file.php?filename=" + filename;
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
}
}
This part would go in the main javafx class:
Platform.runLater(new Runnable() {
#Override
public void run() {
browser2 = new WebView();
webEngine = browser2.getEngine();
appREF = new JavaApp(cloudFrame);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
#Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win
= (JSObject) webEngine.executeScript("window");
// this next line registers the JavaApp class with the page... you can then call it from javascript using "app.method_name".
win.setMember("app", appREF);
}
}
});
You may not need the frame reference... I was hacking some of my own code to test this out and the ref was useful for other things...
I am using LWUIT 1.5 tabs to show notifications. I have three Tabs and I fetch notifications from a php web service. I successfully fetched list of notifications for first Tab. But for next two Tabs I am failing to understand what code I should write to
Detect that second/third Tab is clicked. I know how to add commandListener to a Button. What commandListener is there for Tab selection?
How to refresh content of a Tab when new data is received from the server?
private void showNotificationList() {
try {
Form f = new Form("Notifications");
f.setScrollable(false);
f.setLayout(new BorderLayout());
final List list = new List(getNotifications()); //gets hashtables - notices
list.setRenderer(new GenericListCellRenderer(createGenericRendererContainer(), createGenericRendererContainer()));
list.setSmoothScrolling(true);
//System.out.println("adding list component to listview");
list.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int i = list.getSelectedIndex();
noticeDetailsForm(notices[i]);
//Dialog. show( "title", notices[i].toString(), "ok", "exitt");
}
});
//Container c2 = new Container(new BoxLayout(BoxLayout.Y_AXIS));
//c2.addComponent(list);
Tabs tabs = new Tabs(Tabs.TOP);
tabs.addTab("Recent", list);
tabs.addTab("Urgent", new Label("urgent goes here"));
tabs.addTab("Favourites", new Label("favs goes here"));
//f.addComponent(tabs);
f.addComponent(BorderLayout.CENTER, tabs);
Command backComm = new Command("Back") {
public void actionPerformed(ActionEvent ev) {
Dashboard.dbInstance.setUpDashboard();
}
};
f.addCommand(backComm);
//System.out.println("showing lsit form");
f.show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private Container createGenericRendererContainer() throws IOException { //System.out.println("container called");
//System.out.println("container called");
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label xname = new Label("");
Label description = new Label();
Label focus = new Label("");
Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS));
xname.setName("Name");
xname.getStyle().setBgTransparency(0);
xname.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
//description.setFocusable(true);
description.setName("Description");
cnt.addComponent(xname);
cnt.addComponent(description);
c.addComponent(BorderLayout.CENTER, cnt);
Button thumb = new Button(Image.createImage("/res/home-work.png"));
//Image img = Image.createImage("/res/home-work.png");
c.addComponent(BorderLayout.WEST, thumb);
return c;
}
private Hashtable[] getNotifications() {
int total = notices.length;
//System.out.println(total);
Hashtable[] data = new Hashtable[total];
//Hashtable[] data = new Hashtable[5];
/data[0] = new Hashtable();
data[0].put("Name", "Shai");
data[0].put("Surname", "Almog");
data[0].put("Selected", Boolean.TRUE);/
for (int i = 0; i < total; i++) {
data[i] = new Hashtable();
//System.out.println(notices[i].getName());
data[i].put("Name", notices[i].getName());
data[i].put("Description", notices[i].getDescription());
data[i].put("Id", Integer.toString(notices[i].getId()));
}
return data;
}
1)I had the same problem and I solved it by overriding Keyreleased of the Form not the Tab
and inside it I check for the component that is focused and if it is the Tab get "tab.selectedIndex" to detect in which Tab I am and load appropriate data .
Here is Sample code(this inside the my derived form that extends Form )
**
public void keyReleased(int keyCode) {
Component p=this.getFocused();
String str= p.getClass().getName();
if(str.toLowerCase().indexOf("radiobutton")!=-1){ // Radiobutton because when u
Here do tab specific work focus on the
tab it returns radiobutton.
lwuit understands tabs as list
of radiobuttons
}**
2)and about refreshing the data I did a solution and I don't Know if its right
I get the new data , create new List and remove the old one and attach the new one then
call Form.repaint();
From this example http://www.smartclient.com/smartgwt/showcase/#tree_databinding_local , I started to implement my own tree structure dynamically (TreeGrid). When I try to render it, I get this error (title).
public class ProjectTreeGridScreen extends Screen {
Tree tree;
#Override
protected void onLoad() {
super.onLoad();
TreeGrid treeGrid = new TreeGrid();
setPageTitle(Util.C.projectListTitle());
treeGrid.setWidth(600);
treeGrid.setHeight(400);
TreeGridField projectTree = new TreeGridField("ProjectName", "Project Tree");
TreeGridField projectPath = new TreeGridField("ProjectPath", "Complete path");
TreeGridField projectDescription = new TreeGridField("ProjectDescription", "Description");
TreeGridField projectInfo = new TreeGridField("ProjectInfo", "Information");
treeGrid.setFields(projectTree, projectPath, projectDescription, projectInfo);
treeGrid.setData(tree);
add(treeGrid);
}
#Override
protected void onInitUI() {
super.onInitUI();
tree = new Tree();
tree.setModelType(TreeModelType.PARENT);
tree.setNameProperty("ProjectName");
tree.setIdField("ProjectItem");
tree.setParentIdField("ProjectParent");
tree.setShowRoot(true);
populateProjects();
}
protected void populateProjects() {
Util.PROJECT_SVC.visibleProjects(
new ScreenLoadCallback<List<Project>>(this) {
#Override
public void preDisplay(final List<Project> result) {
tree.setData(ProjectTreeGridBuilder.fromRepositories(result));
}
});
}
}
what do you mean by "x"? Normally, If a component has been drawn on the window (implicit or explicit call to draw), you cannot change it's properties values. So the only possible solution is to recreate the object with the new X value each time it is changing.