How i can refresh listfragment? no tutorials from net work :(
i have no idea, how reload this listfragment. I tried reload by transaktionmanager, but its colide with ActionBar.TabListener, this is not support.v4. how can i retrieve new data from loadermanager and update listfragment?
Activity:
package sk.test;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import java.util.Locale;
import sk.test.frags.TodoFragment;
import sk.test.prefs.EditPreferences;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
private TodoFragment todoFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), EditPreferences.class));
return true;
case R.id.refresh:
//HERE CODE FOR RELOAD todoFragment.reloadData() ????
return true;
default:
return true;
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private boolean wantDone = false;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
todoFragment = new TodoFragment();
this.wantDone = position == 0 ? false : true;
Bundle args = new Bundle();
args.putBoolean(TodoFragment.TASK_TYPE, this.wantDone);
todoFragment.setArguments(args);
return todoFragment;
}
#Override
public int getCount() {
return 2;
}
public boolean getWantDone(){
return this.wantDone;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.todotask_planned).toUpperCase(l);
case 1:
return getString(R.string.todotask_done).toUpperCase(l);
}
return null;
}
}
}
ListFragment:
package sk.test;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import sk.test.adapter.CustomArrayAdapter;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
/**
* Created by Peter on 29.7.2013.
*/
public class TodoFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Item>> {
public static String TASK_TYPE = "taskType";
private static final String XML_SOURCE = "http://******/";
private boolean wantDone = false;
CustomArrayAdapter mAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("TODOLIST", "DataListFragment.onActivityCreated");
this.wantDone = getArguments().getBoolean(TASK_TYPE);
// Initially there is no data
setEmptyText("No Data Here");
// Create an empty adapter we will use to display the loaded data.
mAdapter = new CustomArrayAdapter(getActivity());
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
setHasOptionsMenu(true);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("TODOLIST", "Item clicked: " + id);
}
#Override
public Loader<List<Item>> onCreateLoader(int i, Bundle bundle) {
Log.i("TODOLIST", "DataListFragment.onCreateLoader");
return new DataListLoader(getActivity(), this.wantDone);
}
#Override
public void onLoadFinished(Loader<List<Item>> listLoader, List<Item> items) {
mAdapter.setData(items);
Log.i("TODOLIST", "DataListFragment.onLoadFinished");
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
#Override
public void onLoaderReset(Loader<List<Item>> listLoader) {
}
public void reloadData(){
//UPDATE LIST.. HOW?
}
}
Loader:
package sk.test;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import sk.test.commons.Commons;
import sk.test.xml.Item;
import sk.test.xml.Response;
/**
* Created by Peter Chovan on 29.7.2013.
*/
public class DataListLoader extends AsyncTaskLoader<List<Item>> {
private List<Item> todoTasks;
private boolean wantDone;
SharedPreferences prefs;
public DataListLoader(Context context, boolean wantDone) {
super(context);
this.wantDone = wantDone;
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
}
#Override
public List<Item> loadInBackground() {
Log.i("TODOLIST", "DataListLoader.loadInBackground");
String xmlData = getXmlData(prefs.getString("service_url", "http://*****/"));
List<Item> entries = new ArrayList<Item>();
String state = wantDone ? "WANT DONE" : "WANT PLANNED";
if (xmlData != null) {
xmlData = xmlData.replaceAll("<([^/]+?)/>", "<$1> </$1>");
Serializer serializer = new Persister();
try {
Response res = serializer.read(Response.class, xmlData, false);
for (Item i : res.getItems().getItem()) {
if (i.isDone() == wantDone) {
entries.add(i);
}
}
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TEST serializer", s.toString());
}
}
} else {
Log.e("TODOLIST DATA", "NULL");
}
return entries;
}
public String getXmlData(String uri) {
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Accept", "application/xml");
Map<String, String> params = new HashMap<String, String>();
params.put("user", prefs.getString("service_login", "devel"));
params.put("pass", prefs.getString("service_password", "devel"));
params.put("class", "GetList");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(Commons.getRequestData(params)); //add request params
wr.flush();
String xmlData = readStream(con.getInputStream());
wr.close();
con.disconnect();
return xmlData;
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "doInBackground" + s.toString());
}
}
return null;
}
private String readStream(InputStream in) {
BufferedReader reader = null;
String result = "";
try {
reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
return result;
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + s.toString());
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + "Error while closing Reader");
}
}
}
}
return null;
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
#Override
public void deliverResult(List<Item> listOfData) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (listOfData != null) {
onReleaseResources(listOfData);
}
}
List<Item> oldApps = listOfData;
todoTasks = listOfData;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(listOfData);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; now that the new result is delivered we
// know that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to start the Loader.
*/
#Override
protected void onStartLoading() {
if (todoTasks != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(todoTasks);
}
if (takeContentChanged() || todoTasks == null) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
#Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
#Override
public void onCanceled(List<Item> apps) {
super.onCanceled(apps);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(apps);
}
/**
* Handles a request to completely reset the Loader.
*/
#Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (todoTasks != null) {
onReleaseResources(todoTasks);
todoTasks = null;
}
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(List<Item> apps) {
}
}
Use this to restart the Loader: getLoaderManager().restartLoader(0, null, this);
Related
JavaFx-14 put this method in the TableColumnHeader, rather than in the Skin. How does one find a TableColumnHeader from a TableColumn and a TableView?
Don't know if you still need this, but if anyone else is interested, this is how I surpassed the problem in java, based on David Goodenough's scala code above.
The class for the TableSkin
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TableView;
import javafx.scene.control.skin.NestedTableColumnHeader;
import javafx.scene.control.skin.TableColumnHeader;
import javafx.scene.control.skin.TableHeaderRow;
import javafx.scene.control.skin.TableViewSkin;
import java.util.ArrayList;
import java.util.List;
public class CustomTableViewSkin extends TableViewSkin<Track> {
private List<CustomTableColumnHeader> columnHeadersList = new ArrayList<>();
private class CustomTableColumnHeader extends TableColumnHeader {
/**
* Creates a new TableColumnHeader instance to visually represent the given
* {#link TableColumnBase} instance.
*
* #param tc The table column to be visually represented by this instance.
*/
public CustomTableColumnHeader(TableColumnBase tc) {
super(tc);
}
public void resizeColumnToFitContent() {
super.resizeColumnToFitContent(-1);
}
}
public CustomTableViewSkin(TableView<Track> tableView) {
super(tableView);
}
#Override
protected TableHeaderRow createTableHeaderRow() {
return new TableHeaderRow(this) {
#Override
protected NestedTableColumnHeader createRootHeader() {
return new NestedTableColumnHeader(null) {
#Override
protected TableColumnHeader createTableColumnHeader(TableColumnBase col) {
CustomTableColumnHeader columnHeader = new CustomTableColumnHeader(col);
if (columnHeadersList == null) {
columnHeadersList = new ArrayList<>();
}
columnHeadersList.add(columnHeader);
return columnHeader;
}
};
}
};
}
public void resizeColumnToFit() {
if (!columnHeadersList.isEmpty()) {
for (CustomTableColumnHeader columnHeader : columnHeadersList) {
columnHeader.resizeColumnToFitContent();
}
}
}
}
And the class for the TableView
import javafx.scene.control.TableView;
public class CustomTableView extends TableView<Foo> {
private final CustomTableViewSkin thisSkin;
public CustomTableView() {
super();
setSkin(thisSkin = new CustomTableViewSkin(this));
}
public void resizeColumnsToFitContent() {
if (thisSkin != null && getSkin() == thisSkin) {
thisSkin.resizeColumnToFit();
}
}
}
Well this code is Scala not Java, but for the record the code below works:-
skin = new TableViewSkin(this) {
override protected def createTableHeaderRow:TableHeaderRow = {
new TableHeaderRow(this) {
override protected def createRootHeader:NestedTableColumnHeader = {
new NestedTableColumnHeader(null) {
override protected def createTableColumnHeader(col:TableColumnBase[_,_]) = {
val tableColumnHeader = new MyTableColumnHeader(col)
if(col == null || col.getColumns.isEmpty || col == getTableColumn) tableColumnHeader else new NestedTableColumnHeader(col)
}
}
}
}
}
}
private class MyTableColumnHeader(tc:TableColumnBase[_,_]) extends TableColumnHeader(tc) {
def resizeCol():Double = {
resizeColumnToFitContent(-1)
width.value
}
}
and then when I want to use it I use kleopatra's suggestion and:-
val w = columns.map { col =>
// To find the TableColumnHeader we can use column.getStyleableNode as suggested by kleopatra on StackOverflow:-
// you get the header from coumn.getStyleableNode (took a moment, had to check if it's really implemented) – kleopatra Jul 1 at 20:46
col.getStyleableNode() match {
case mtch:MyTableColumnHeader => mtch.resizeCol
case _ => col.width.get
}
}.sum
This is a hack'ish way of getting the TableColumnHeader:
public TableColumnHeader getTableColumnHeader(TableView<?> table, int index) {
return (TableColumnHeader) table.queryAccessibleAttribute(AccessibleAttribute.COLUMN_AT_INDEX, index);
}
Or, as #kleopatra suggested, for a non-hack'ish approach you can do:
public TableColumnHeader getTableColumnHeader(TableView<?> table, int index) {
return (TableColumnHeader) table.getColumns().get(index).getStyleableNode();
}
Make sure that the TableView is part of the scene graph.
However, the resizeColumnToFitContent method is protected and you won't be able to access it.
I have been trying to Design an App That has PANEL like Google Drawers.
• MainActivity
package skynet.com.testnavigationpanel;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends ActionBarActivity
implements NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
private Toolbar mToolbar;
Intent i=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.fragment_drawer);
// Set up the drawer.
mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), mToolbar);
// populate the navigation drawer
mNavigationDrawerFragment.setUserData("Falcon Shield", "We Protect Your Device!", BitmapFactory.decodeResource(getResources(), R.drawable.shieldavatar));
}
public void login_signup(View v)
{
switch(v.getId())
{
case R.id.log_in:
i=new Intent(this,Login.class);
startActivityForResult(i, 500);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
break;
case R.id.sign_up:
i=new Intent(this,Signup.class);
startActivityForResult(i, 500);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
#Override
public void onNavigationDrawerItemSelected(int position)
{
// update the main content by replacing fragments
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onSectionAttached(int anInt) {
}
}
•NavigationDrawerFragment
package skynet.com.testnavigationpanel;
import android.app.Activity;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment implements NavigationDrawerCallbacks {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mActionBarDrawerToggle;
private DrawerLayout mDrawerLayout;
private RecyclerView mDrawerList;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mDrawerList = (RecyclerView) view.findViewById(R.id.drawerList);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mDrawerList.setLayoutManager(layoutManager);
mDrawerList.setHasFixedSize(true);
final List<NavigationItem> navigationItems = getMenu();
NavigationDrawerAdapter adapter = new NavigationDrawerAdapter(navigationItems);
adapter.setNavigationDrawerCallbacks(this);
mDrawerList.setAdapter(adapter);
selectItem(mCurrentSelectedPosition);
return view;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
public ActionBarDrawerToggle getActionBarDrawerToggle() {
return mActionBarDrawerToggle;
}
public DrawerLayout getDrawerLayout() {
return mDrawerLayout;
}
#Override
public void onNavigationDrawerItemSelected(int position) {
selectItem(position);
}
public List getMenu() {
List items= new ArrayList<>();
items.add(new NavigationItem(getString(R.string.homeFrag),getResources().getDrawable(R.drawable.ic_home)));
items.add(new NavigationItem(getString(R.string.loginFrag),getResources().getDrawable(R.drawable.ic_login)));
items.add(new NavigationItem(getString(R.string.signupFrag),getResources().getDrawable(R.drawable.ic_signup)));
items.add(new NavigationItem(getString(R.string.settingFrag),getResources().getDrawable(R.drawable.ic_setting )));
items.add(new NavigationItem(getString(R.string.shareFrag),getResources().getDrawable(R.drawable.ic_share )));
items.add(new NavigationItem(getString(R.string.aboutFrag),getResources().getDrawable(R.drawable.ic_about )));
return items;
}
public void showBackButton(){
if(getActivity()instanceof ActionBarActivity){
((ActionBarActivity)getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
* #param toolbar The Toolbar of the activity.
*/
public void setup(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
mFragmentContainerView = (View) getActivity().findViewById(fragmentId).getParent();
mDrawerLayout = drawerLayout;
mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myPrimaryDarkColor));
mActionBarDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) return;
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) return;
if (!mUserLearnedDrawer) {
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mActionBarDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
((NavigationDrawerAdapter) mDrawerList.getAdapter()).selectPosition(position);
}
public void openDrawer() {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
public void closeDrawer() {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mActionBarDrawerToggle.onConfigurationChanged(newConfig);
}
public void setUserData(String user, String email, Bitmap avatar) {
ImageView avatarContainer = (ImageView) mFragmentContainerView.findViewById(R.id.imgAvatar);
((TextView) mFragmentContainerView.findViewById(R.id.txtUserEmail)).setText(email);
((TextView) mFragmentContainerView.findViewById(R.id.txtUsername)).setText(user);
avatarContainer.setImageDrawable(new RoundImage(avatar));
}
public View getGoogleDrawer() {
return mFragmentContainerView.findViewById(R.id.googleDrawer);
}
public static class RoundImage extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;
public RoundImage(Bitmap bitmap) {
mBitmap = bitmap;
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRectF.set(bounds);
}
#Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
#Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}
#Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}
#Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}
public Bitmap getBitmap() {
return mBitmap;
}
}
}
Kindly Guide me in Mentioning the Right code into Below Method of MainActivity.
onNavigationDrawerItemSelect(int position)
{
//codes for fragments That i dont Know how to write
}
My Fragment Class(Please Check the Code if its Right or needs to be changed)
package skynet.com.testnavigationpanel;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Evan on 28-Dec-15.
*/
public class HomeFragment extends Fragment {
public static HomeFragment newInstance(){
HomeFragment fragment=new HomeFragment();
return fragment;
}
public HomeFragment()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.activity_main,container,false);
return rootView;
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
((MainActivity)activity).onSectionAttached(1);
}
}
Same Goes with my Other fragments for login, signup, about, share, etc..with Relevant Changes in Layout id and Names.
Devs, Kindly Help ! Thanks
i have a question for this sample code.
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CopyOfTreeViewSample extends Application {
public static Image folderCollapseImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/folder.png"));
public static Image folderExpandImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/folder-open.png"));
public static Image fileImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/text-x-generic.png"));
public static Image rootImage = new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/computer.png"));
private TreeView treeView;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Sample");
stage.setWidth(300);
stage.setHeight(500);
VBox vbox = new VBox();
vbox.setLayoutX(20);
vbox.setLayoutY(20);
TreeItem<String> root = new SimpleFileTreeItem(Paths.get("C:\\Users\\Jake"), true);
treeView = new TreeView<String>(root);
Button b = new Button("Change");
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
// TODO Auto-generated method stub
////// How do i this section write code?//////
}
});
vbox.getChildren().addAll(treeView,b);
vbox.setSpacing(10);
((Group) scene.getRoot()).getChildren().add(vbox);
stage.setScene(scene);
stage.show();
}
public class SimpleFileTreeItem extends TreeItem<String> {
private boolean isRoot = false;
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
private boolean isLeaf;
private boolean isDirectory;
public boolean isDirectory(){return(this.isDirectory);}
private String fullPath;
public String getFullPath(){return(this.fullPath);}
public SimpleFileTreeItem(Path f, Boolean flag) {
super(f.toString());
fullPath = f.toString();
isRoot = flag;
if(!isRoot)
{
if(Files.isDirectory(f))
{
isDirectory = true;
this.setGraphic(new ImageView(folderCollapseImage));
}
else
{
isDirectory = false;
this.setGraphic(new ImageView(fileImage));
}
//set the value
if(!fullPath.endsWith(File.separator)){
String value=f.toString();
int indexOf=value.lastIndexOf(File.separator);
if(indexOf>0){
this.setValue(value.substring(indexOf+1));
}else{
this.setValue(value);
}
}
this.addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler(){
#Override
public void handle(Event e){
SimpleFileTreeItem source=(SimpleFileTreeItem)e.getSource();
if(source.isDirectory()&&source.isExpanded()){
ImageView iv=(ImageView)source.getGraphic();
iv.setImage(folderExpandImage);
}
}
});
this.addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler(){
#Override
public void handle(Event e){
SimpleFileTreeItem source=(SimpleFileTreeItem)e.getSource();
if(source.isDirectory()&&!source.isExpanded()){
ImageView iv=(ImageView)source.getGraphic();
iv.setImage(folderCollapseImage);
}
}
});
}
else
{
this.setExpanded(true);
if(Files.isDirectory(f))
{
isDirectory = true;
this.setGraphic(new ImageView(rootImage));
}
else
{
isDirectory = false;
this.setGraphic(new ImageView(fileImage));
}
}
}
#Override
public ObservableList<TreeItem<String>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
/*
* First getChildren() call, so we actually go off and determine the
* children of the File contained in this TreeItem.
*/
super.getChildren().setAll(buildChildren(this));
}
return super.getChildren();
}
#Override
public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
File f = new File(fullPath);
isLeaf = f.isFile();
}
return isLeaf;
}
/**
* Returning a collection of type ObservableList containing TreeItems, which
* represent all children available in handed TreeItem.
*
* #param TreeItem
* the root node from which children a collection of TreeItem
* should be created.
* #return an ObservableList<TreeItem<File>> containing TreeItems, which
* represent all children available in handed TreeItem. If the
* handed TreeItem is a leaf, an empty list is returned.
*/
private ObservableList<TreeItem<String>> buildChildren(TreeItem<String> TreeItem) {
File f = new File(fullPath);
if (f != null && f.isDirectory()) {
File[] files = f.listFiles();
if (files != null) {
ObservableList<TreeItem<String>> children = FXCollections
.observableArrayList();
for (File childFile : files) {
children.add(new SimpleFileTreeItem(childFile.toPath(), false));
}
return children;
}
}
return FXCollections.emptyObservableList();
}
}
I want to select the file that corresponds to the path when the button is pressed .
my eclipse project path is c:\java\samplecode.
I was trying to solve by using Absolutepath the result is c:\java\samplecode\samplefile.txt
i want this path.(c:\Users\jake\samplefile.txt)
Thank you for advice and tips.
Using the setup you have, you should be able to do
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
SimpleFileTreeItem<String> selectedItem = (SimpleFileTreeItem)treeView.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
String pathString = selectedItem.getFullPath();
}
}
});
(If you also do
b.disableProperty().bind(
Bindings.isNull(treeView.getSelectionModel().selectedItemProperty()));
then you can safely skip the check for null in the handler.)
I think a better approach would be to make SimpleFileTreeItem a TreeItem<Path>. Then you just keep the Path as the value of the tree item, and you can use a cell factory to just display the file name.
Here is an example using this approach. I took out the images (so it can be executed without relying on external resources) and also a lot of the other unnecessary code.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CopyOfTreeViewSample extends Application {
private TreeView<Path> treeView;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Sample");
stage.setWidth(300);
stage.setHeight(500);
VBox vbox = new VBox();
vbox.setPadding(new Insets(20));
TreeItem<Path> root = new SimpleFileTreeItem(
Paths.get(System.getProperty("user.home")));
root.setExpanded(true);
treeView = new TreeView<Path>(root);
treeView.setCellFactory(treeView -> new TreeCell<Path>() {
#Override
public void updateItem(Path path, boolean empty) {
super.updateItem(path, empty);
if (empty) {
setText(null);
} else {
setText(path.getFileName().toString());
}
}
});
Button b = new Button("Change");
b.disableProperty().bind(Bindings.isNull(treeView.getSelectionModel().selectedItemProperty()));
b.setOnAction(event -> {
Path selectedPath = treeView.getSelectionModel().getSelectedItem().getValue() ;
// do something with selectedPath...
System.out.println(selectedPath);
});
vbox.getChildren().addAll(treeView, b);
vbox.setSpacing(10);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public class SimpleFileTreeItem extends TreeItem<Path> {
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
private boolean isLeaf;
public boolean isDirectory() {
return Files.isDirectory(getValue());
}
public SimpleFileTreeItem(Path f) {
super(f);
}
#Override
public ObservableList<TreeItem<Path>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
/*
* First getChildren() call, so we actually go off and determine
* the children of the File contained in this TreeItem.
*/
super.getChildren().setAll(buildChildren());
}
return super.getChildren();
}
#Override
public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
isLeaf = Files.exists(getValue()) && ! Files.isDirectory(getValue());
}
return isLeaf;
}
/**
* Returning a collection of type ObservableList containing TreeItems,
* which represent all children of this TreeITem.
*
*
* #return an ObservableList<TreeItem<File>> containing TreeItems, which
* represent all children available in this TreeItem. If the
* handed TreeItem is a leaf, an empty list is returned.
*/
private ObservableList<TreeItem<Path>> buildChildren() {
if (Files.isDirectory(getValue())) {
try {
return Files.list(getValue())
.map(SimpleFileTreeItem::new)
.collect(Collectors.toCollection(() -> FXCollections.observableArrayList()));
} catch (IOException e) {
e.printStackTrace();
return FXCollections.emptyObservableList();
}
}
return FXCollections.emptyObservableList();
}
}
}
I am building my first javafx (2.2) application. The user selects a number of tasks to execute, by selecting checkboxes in a treeview.
I am trying to figure out how, after a task completes, to change the style of the related TreeCell.
public class WorkbenchSscce extends Application {
public static void main(String...args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
final CheckBoxTreeItem<String> rootNode = new CheckBoxTreeItem<>("parent");
final CheckBoxTreeItem<String> taskOne = new CheckBoxTreeItem<>("task one");
final CheckBoxTreeItem<String> taskTwo = new CheckBoxTreeItem<>("task two");
rootNode.getChildren().addAll(taskOne, taskTwo);
TreeView<String> treeView = new TreeView<>(rootNode);
treeView.setEditable(true);
treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
treeView.setShowRoot(false);
Button executeButton = new Button("Execute");
executeButton.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (taskOne.isSelected()) {
executeTask(1);
/**
* ?????
* give the TreeCell for taskOne a green background, to indicate it is complete
* ?????
*/
}
if (taskTwo.isSelected()) {
executeTask(2);
/**
* ?????
* give the TreeCell for taskTwo a green background, to indicate it is complete
* ?????
*/
}
}
});
VBox box = new VBox();
box.getChildren().addAll(treeView, executeButton);
Scene scene = new Scene(box);
stage.setScene(scene);
stage.show();
}
public void executeTask(int input) {
// do something
}
}
I can see how to style the CheckBoxTreeCells at creation time.
I see how to change styles when user events happen to the TreeView (using EventListeners).
But I can't see how to style a tree cell when the source of the event is internal to the application. See comments in the MouseEvent handler above.
The key is to observe the state of the Task (I used a Service instead of a Task in this example, as it can be run multiple times) from the cell factory. To do this, you need the data type of the TreeItem to be something that has an observable property representing the current state of the task/service. The easiest way to do this, if you can, is to make the data type of the TreeItems the Task itself (so conceptually, your TreeView is displaying Tasks).
This is slightly subtle as the item (i.e. Task) represented by a given cell can change. In this example I just observe the cell's item property, removing a listener that observes the task's state from an item the cell is no longer representing and adding the listener to the item it now represents. If you use the EasyBind framework (and Java 8, which it requires), you can clean this up a bit, doing something like
EasyBind.select(cell.itemProperty())
.selectObject(Service::stateProperty)
.addListener((ov, oldState, newState) -> updateCell(cell) );
Full example (using JavaFX 2.2, though I compiled under Java 8, so some Java 8 features may have snuck in):
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
final BorderPane root = new BorderPane();
final TreeView<SelectableService> tree = new TreeView<>();
final TreeItem<SelectableService> treeRoot = new TreeItem<>(new SelectableService("Parent"));
for (int i=1; i<=10; i++) {
treeRoot.getChildren().add(new TreeItem<>(new SelectableService("Task "+i)));
}
tree.setRoot(treeRoot);
final Button startButton = new Button("Start selected tasks");
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for (SelectableService service : findSelectedTasks(treeRoot)) {
service.restart();
}
}
});
final HBox controls = new HBox(5);
controls.getChildren().add(startButton);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
root.setCenter(tree);
root.setBottom(controls);
tree.setCellFactory(new Callback<TreeView<SelectableService>, TreeCell<SelectableService>>() {
#Override
public TreeCell<SelectableService> call(TreeView<SelectableService> param) {
return createCell();
}
});
Scene scene = new Scene(root, 400, 600);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
private CheckBoxTreeCell<SelectableService> createCell() {
// CheckBoxTreeCell whose check box state is mapped to the selected property of the task:
final CheckBoxTreeCell<SelectableService> cell = new CheckBoxTreeCell<SelectableService>(new Callback<TreeItem<SelectableService>, ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(TreeItem<SelectableService> treeItem) {
SelectableService task = treeItem.getValue();
if (task != null) {
return task.selectedProperty();
} else {
return null ;
}
}
});
final ChangeListener<State> taskStateListener = new ChangeListener<State>() {
#Override
public void changed(
ObservableValue<? extends State> observable,
State oldValue, State newValue) {
updateCell(cell);
}
};
cell.itemProperty().addListener(new ChangeListener<SelectableService>() {
#Override
public void changed(
ObservableValue<? extends SelectableService> observable,
SelectableService oldTask, SelectableService newTask) {
if (oldTask != null) {
oldTask.stateProperty().removeListener(taskStateListener);
}
if (newTask != null) {
newTask.stateProperty().addListener(taskStateListener);
}
updateCell(cell);
}
});
cell.setConverter(new StringConverter<TreeItem<SelectableService>>() {
#Override
public String toString(TreeItem<SelectableService> treeItem) {
SelectableService task = treeItem.getValue();
if (task == null) {
return null ;
} else {
return task.getName();
}
}
#Override
public TreeItem<SelectableService> fromString(String string) {
// Not supported
throw new UnsupportedOperationException("Uneditable tree cell does not create SelectableTasks");
}
});
return cell;
}
private void updateCell(CheckBoxTreeCell<SelectableService> cell) {
cell.getStyleClass().removeAll(Arrays.asList("running", "finished", "failed"));
SelectableService task = cell.getItem();
if (task != null) {
State state = task.getState();
// Update style class:
if (state == State.RUNNING) {
cell.getStyleClass().add("running");
} else if (state == State.SUCCEEDED) {
cell.getStyleClass().add("finished");
} else if (state == State.FAILED){
cell.getStyleClass().add("failed");
}
}
}
private Set<SelectableService> findSelectedTasks(TreeItem<SelectableService> treeItem) {
Set<SelectableService> selectedTasks = new HashSet<>();
addTaskAndChildTasksIfSelected(selectedTasks, treeItem) ;
return selectedTasks ;
}
private void addTaskAndChildTasksIfSelected(Set<SelectableService> selectedTasks, TreeItem<SelectableService> treeItem) {
SelectableService task = treeItem.getValue();
if (task != null && task.isSelected()) {
selectedTasks.add(task);
}
for (TreeItem<SelectableService> child : treeItem.getChildren()) {
addTaskAndChildTasksIfSelected(selectedTasks, child);
}
}
public static class SelectableService extends Service<Void> {
private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected", false);
public final BooleanProperty selectedProperty() {
return this.selected;
}
public final boolean isSelected() {
return this.selectedProperty().get();
}
public final void setSelected(final boolean selected) {
this.selectedProperty().set(selected);
}
private final ReadOnlyStringWrapper name = new ReadOnlyStringWrapper(this, "name");
private final void setName(String name) {
this.name.set(name);
}
public final String getName() {
return name.get() ;
}
public final ReadOnlyStringProperty nameProperty() {
return name.getReadOnlyProperty();
}
public SelectableService(String name) {
setExecutor(Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t ;
}
}));
setName(name);
}
#Override
public Task<Void> createTask() {
return new Task<Void>() {
#Override
public Void call() throws Exception {
// just a mock task: pauses for a random time, then throws an exception with
// probability 0.25
Random rng = new Random();
Thread.sleep(2000 + rng.nextInt(2000));
if (rng.nextDouble() < 0.25) {
throw new Exception("Task failed");
}
return null ;
}
};
}
}
public static void main(String[] args) {
launch(args);
}
}
application.css is simply
.finished {
-fx-background: green ;
}
.failed {
-fx-background: red ;
}
.running {
-fx-background: yellow ;
}
This is quite considerably cleaner in Java 8, by the way, but since you posted JavaFX 2.2-style code, I assumed you were still using the old version. Java 8 also allows you to use pseudoclasses for the css style, which is a bit nicer (and in general has better performance, though it's a moot point here).
I'm trying to use this to select a value from a Custom Combo Box:
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import static javafx.application.Application.launch;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class MainApp extends Application
{
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage stage)
{
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.setButtonCell(new GroupListCell());
listGroups.setCellFactory(new Callback<ListView<ListGroupsObj>, ListCell<ListGroupsObj>>()
{
#Override
public ListCell<ListGroupsObj> call(ListView<ListGroupsObj> p)
{
return new GroupListCell();
}
});
listGroups.setEditable(true);
listGroups.setConverter..............
// Insert Some data
ListGroupsObj ob = ListGroupsObj.newInstance().groupId(12).groupName("Test");
listGroups.getItems().addAll(ob);
ListGroupsObj osb = ListGroupsObj.newInstance().groupId(13).groupName("Test2");
listGroups.getItems().addAll(osb);
listGroups.setValue(ob);
// Display the selected Group
listGroups.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ListGroupsObj>()
{
#Override
public void changed(ObservableValue<? extends ListGroupsObj> arg0, ListGroupsObj arg1, ListGroupsObj arg2)
{
if (arg2 != null)
{
System.out.println("Selected Group: " + arg1.getGroupId() + " - " + arg2.getGroupName());
}
}
});
final StackPane layout = new StackPane();
layout.getChildren().add(listGroups);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 15;");
stage.setScene(new Scene(layout));
stage.show();
}
class GroupListCell extends ListCell<ListGroupsObj>
{
#Override
protected void updateItem(ListGroupsObj item, boolean empty)
{
super.updateItem(item, empty);
if (item != null)
{
setText(item.getGroupId() + " - " + item.getGroupName());
}
}
}
private List<ListGroupsObj> listGroups;
public static class ListGroupsObj
{
private int groupId;
private String groupName;
public static ListGroupsObj newInstance()
{
return new ListGroupsObj();
}
public ListGroupsObj()
{
}
public ListGroupsObj groupId(int groupId)
{
this.groupId = groupId;
return this;
}
public ListGroupsObj groupName(String groupName)
{
this.groupName = groupName;
return this;
}
public int getGroupId()
{
return groupId;
}
public String getGroupName()
{
return groupName;
}
#Override
public String toString()
{
return groupId + " - " + groupName;
}
}
public class GroupConverter extends StringConverter<ListGroupsObj>
{
#Override
public String toString(ListGroupsObj obj)
{
return obj.getGroupId() + " - " + obj.getGroupName();
}
#Override
public ListGroupsObj fromString(String obj)
{
//TODO when you type for example "45 - NextGroup" you want to take only tyhe number"
return ListGroupsObj.newInstance().groupName(obj);
}
}
}
I get this error when I click outside of the comboBox:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to com.selectmenuexample.MainApp$ListGroupsObj
I found that this can be done using convertor but I'm now aware how to use it. Can you help with this implementation?
Here is what is wrong:
You called your ComboBox listGroups and your List of Items listGroups. So in your start code, you were hiding that variable. So I removed that useless variable since you can manipulate Items directly in the ComboBox.
You had basically three methods/variable doing the exact same things. Converting your Object into a String with a "-" between them. So I removed the GroupConverter and the custom cellFactory. You don't need them because you already have your "toString()" method in your ListGroupsObj which is doing the job.
Then you misunderstood how the ComboBox is working. If it's editable, the ComboBox will allow something to be typed inside the TextField. That's where the StringConverter comes. It will allow you to make the conversion between a String and your ListGroupsObj and the way around.
In order to go from a ListGroupsObj to a String, simply call the "toString()" method on your object.
But in the way around, you should either create a new ListGroupsObj, or verify that what's inside the ComboBox is not already one item of yours. For example, if you select an Item in the comboBox, the fromString() will be called. But you don't want to create a new ListGroupsObj, you just want to isolate the ListGroupsObj inside your items List and returns it.
Now, you have the guaranty that a call to getValue() on your ComboBox will always return an ListGroupsObj object since you have provided a custom and valid StringConverter.
Here is a simplified and working version of your code :
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class MainApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
final ComboBox<ListGroupsObj> comboBox = new ComboBox();
comboBox.setEditable(true);
comboBox.setConverter(new StringConverter<ListGroupsObj>() {
#Override
public String toString(ListGroupsObj obj) {
return obj.toString();
}
#Override
public ListGroupsObj fromString(String obj) {
//Here we try to identify if the given String actually represents one item of our list
for(ListGroupsObj tempObj:comboBox.getItems()){
if(tempObj.toString().equals(obj)){
return tempObj;
}
}
//If not we just create a new one
return ListGroupsObj.newInstance().groupName(obj);
}
});
// Insert Some data
ListGroupsObj ob = ListGroupsObj.newInstance().groupId(12).groupName("Test");
comboBox.getItems().addAll(ob);
ListGroupsObj osb = ListGroupsObj.newInstance().groupId(13).groupName("Test2");
comboBox.getItems().addAll(osb);
comboBox.setValue(ob);
final StackPane layout = new StackPane();
layout.getChildren().add(comboBox);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 15;");
stage.setScene(new Scene(layout));
stage.show();
}
public static class ListGroupsObj {
private int groupId;
private String groupName;
public static ListGroupsObj newInstance() {
return new ListGroupsObj();
}
public ListGroupsObj() {
}
public ListGroupsObj groupId(int groupId) {
this.groupId = groupId;
return this;
}
public ListGroupsObj groupName(String groupName) {
this.groupName = groupName;
return this;
}
public int getGroupId() {
return groupId;
}
public String getGroupName() {
return groupName;
}
#Override
public String toString() {
return groupId + " - " + groupName;
}
}
}
PS: The issue was already raised in the official JavaFX issue Tracker, I'll leave the link here since there is another example in the ticket (login required) : https://javafx-jira.kenai.com/browse/RT-29118