What is the Swing-equivalent to HTML <optgroup> - java

I want my JComboBox to group multiple options together, similar to the HTML optgroup:
<select>
<optgroup label="A">
<option/>
<option/>
</optgroup>
</select>
I could not find any solution for this in Swing. Manipulating the UI-Renderer for the Combobox seems to be a bad idea, as it's OS & L&F-dependent (and they are private so cannot extend).

Consider the following implementation as a basic guide how to apply custom styling and create non-selectable items:
public class ExtendedComboBox extends JComboBox {
public ExtendedComboBox() {
setModel(new ExtendedComboBoxModel());
setRenderer(new ExtendedListCellRenderer());
}
public void addDelimiter(String text) {
this.addItem(new Delimiter(text));
}
private static class ExtendedComboBoxModel extends DefaultComboBoxModel {
#Override
public void setSelectedItem(Object anObject) {
if (!(anObject instanceof Delimiter)) {
super.setSelectedItem(anObject);
} else {
int index = getIndexOf(anObject);
if (index < getSize()) {
setSelectedItem(getElementAt(index+1));
}
}
}
}
private static class ExtendedListCellRenderer
extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
if (!(value instanceof Delimiter)) {
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
} else {
JLabel label = new JLabel(value.toString());
Font f = label.getFont();
label.setFont(f.deriveFont(f.getStyle()
| Font.BOLD | Font.ITALIC));
return label;
}
}
}
private static class Delimiter {
private String text;
private Delimiter(String text) {
this.text = text;
}
#Override
public String toString() {
return text.toString();
}
}
}

You can do this in a custom renderer, as discussed in How to Use Combo Boxes: Providing a Custom Renderer.

I don't believe that there is one simple way of doing this, but there is a way to do it.
I would implement a data model class that indicates the grouping that you've describe above. Place instances of those data models in your javax.swing.ComboBoxModel implementation instance.
You can then implement a javax.swing.ListCellRenderer to format the output as you like with indents for the text data. You may just want to extend the javax.swing.DefaultListCellRenderer or possibly borrow its implementation wholesale from the Java source.
As for the L&F you should be able to stay within normal guidelines by using the above methods and you won't have to fight with figuring out how to implement it. Look at the default Swing components they will provide a lot of insight in to how to deal with L&F.
Additionally, I think there are mechanisms (you'll have to forgive me, it's been YEARS since I've done full Swing development) to allow you to determine if an item is selectable or not.

I was wanting this myself today, and I've spent the day figuring it out piecing things together to implement a similar model with a JList rather than with the suggested JComboBox. I've finally come up with a solution using GlazedLists EventList and SeparatorList with the corresponding DefaultEventListModel. I override the CellRenderer and the DefaultListSelectionModel. In the end I posted my own answer to my own question on this: How to prevent selection of SeparatorList.Separator in a JList?
Here's my final working code:
public class MyFrame extends javax.swing.JFrame {
private final EventList<BibleVersion> bibleVersions;
private final SeparatorList<BibleVersion> versionsByLang;
private boolean[] enabledFlags;
public MyFrame(){
bibleVersions = new BasicEventList<>();
bibleVersions.add(new BibleVersion("CEI2008", "Testo della Conferenza Episcopale Italiana", "2008", "Italian"));
bibleVersions.add(new BibleVersion("LUZZI", "Diodati Nuova Riveduta - Luzzi", "1927", "Italian"));
bibleVersions.add(new BibleVersion("NVBSE", "Nova Vulgata - Bibliorum Sacrorum Editio", "1979", "Latin"));
bibleVersions.add(new BibleVersion("NABRE", "New American Bible - Revised Edition", "2011", "English"));
bibleVersions.add(new BibleVersion("KJV", "King James Version", "1611", "English"));
versionsByLang = new SeparatorList<>(bibleVersions, new VersionComparator(),1, 1000);
int listLength = versionsByLang.size();
enabledFlags = new boolean[listLength];
ListIterator itr = versionsByLang.listIterator();
while(itr.hasNext()){
enabledFlags[itr.nextIndex()] = !(itr.next().getClass().getSimpleName().equals("GroupSeparator"));
}
jList = new javax.swing.JList();
jList.setModel(new DefaultEventListModel<>(versionsByLang));
jList.setCellRenderer(new VersionCellRenderer());
jList.setSelectionModel(new DisabledItemSelectionModel());
ListSelectionModel listSelectionModel = jList.getSelectionModel();
listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
}
public static class BibleVersion {
private String abbrev;
private String fullname;
private String year;
private String lang;
public BibleVersion(String abbrev, String fullname, String year, String lang) {
this.abbrev = abbrev;
this.fullname = fullname;
this.year = year;
this.lang = lang;
}
public String getAbbrev() {
return abbrev;
}
public void setAbbrev(String abbrev) {
this.abbrev = abbrev;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
#Override
public String toString() {
return this.getAbbrev() + " — " + this.getFullname() + " (" + this.getYear() + ")"; //To change body of generated methods, choose Tools | Templates.
}
}
private static class VersionComparator implements Comparator<BibleVersion> {
#Override
public int compare(BibleVersion o1, BibleVersion o2) {
return o1.getLang().compareTo(o2.getLang());
}
}
private static class VersionCellRenderer extends DefaultListCellRenderer{
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof SeparatorList.Separator) {
SeparatorList.Separator separator = (SeparatorList.Separator) value;
BibleVersion bibleversion = (BibleVersion)separator.getGroup().get(0);
String lbl = "-- " + bibleversion.getLang() + " --";
label.setText(lbl);
label.setFont(label.getFont().deriveFont(Font.BOLD));
label.setBackground(Color.decode("#004400"));
label.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
label.setEnabled(false);
} else {
label.setFont(label.getFont().deriveFont(Font.PLAIN));
label.setBorder(BorderFactory.createEmptyBorder(0,15,0,0));
}
return label;
}
}
private class DisabledItemSelectionModel extends DefaultListSelectionModel {
private static final long serialVersionUID = 1L;
#Override
public void setSelectionInterval(int index0, int index1) {
if(index0 < index1){
for (int i = index0; i <= index1; i++){
if(enabledFlags[i]){
super.addSelectionInterval(i, i);
}
}
}
else if(index1 < index0){
for (int i = index1; i <= index0; i++){
if(enabledFlags[i]){
super.addSelectionInterval(i, i);
}
}
}
else if(index0 == index1){
if(enabledFlags[index0]){ super.setSelectionInterval(index0,index0); }
}
}
#Override
public void addSelectionInterval(int index0, int index1) {
if(index0 < index1){
for (int i = index0; i <= index1; i++){
if(enabledFlags[i]){
super.addSelectionInterval(i, i);
}
}
}
else if(index1 < index0){
for (int i = index1; i <= index0; i++){
if(enabledFlags[i]){
super.addSelectionInterval(i, i);
}
}
}
else if(index0 == index1){
if(enabledFlags[index0]){ super.addSelectionInterval(index0,index0); }
}
}
}
private class SharedListSelectionHandler implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
StringBuilder output = new StringBuilder();
int firstIndex = e.getFirstIndex();
int lastIndex = e.getLastIndex();
boolean isAdjusting = e.getValueIsAdjusting();
output.append("Event for indexes ");
output.append(firstIndex);
output.append(" - ");
output.append(lastIndex);
output.append("; isAdjusting is ");
output.append(isAdjusting);
output.append("; selected indexes:");
if (lsm.isSelectionEmpty()) {
output.append(" <none>");
} else {
// Find out which indexes are selected.
int minIndex = lsm.getMinSelectionIndex();
int maxIndex = lsm.getMaxSelectionIndex();
for (int i = minIndex; i <= maxIndex; i++) {
if (lsm.isSelectedIndex(i)) {
output.append(" ");
output.append(i);
}
}
}
output.append(System.getProperty("line.separator"));
System.out.println(output.toString());
}
}
}

Related

Java Table model data disappearing

I've run into a very strange issue. I wrote a model for a table and for the most part it works perfect. When I update the row data via the setValueAt function it works and the data in the ArrayList is updated and complete. But when i run the getTotalPay function the same array is empty and i get a null value exception.
I've rewrote the code a number of different ways and tried a couple of different approaches to the problem but the problem persists. I know i've done something wrong i just cannot figure out what the problem is. After search the net and not finding a solution i'm posting this.
Things i've tried are replacing the variable, putting the data into two different variables.
Here is the model
public class WeeklyWagesModel extends AbstractTableModel {
private String defaultValue = "Click to edit";
private String[] headings = { "Date From", "Date To", "Wages", "Pay Date" };
private ArrayList<String[]> theData = new ArrayList<String[]>();
public WeeklyWagesModel() {
theData.add(createDefaultRow());
}
#Override
public int getColumnCount() {
return headings.length;
}
public String getColumnName(int col) {
return headings[col];
}
#Override
public int getRowCount() {
return theData.size();
}
#Override
public Object getValueAt(int row, int col) {
return theData.get(row)[col];
}
public boolean isCellEditable(int row, int col) {
return true;
}
public void setValueAt(Object value, int row, int col) {
theData.get(row)[col] = String.valueOf(value);
if (row == (theData.size() - 1)) {
theData.add(createDefaultRow());
}
fireTableDataChanged();
}
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
public ArrayList<String[]> getData() {
return theData;
}
public String getTotalPay() {
System.out.println("Total Pay: " + theData.size());
BigDecimal total = BigDecimal.ZERO;
for (String[] eachRow : theData) {
if (StringUtils.isNumeric(eachRow[2])) {
total.add(new BigDecimal(eachRow[2]));
}
}
return NumberFormat.getCurrencyInstance().format(total);
}
public String getTotalWeeks() {
return "";
}
private String[] createDefaultRow() {
String[] newRow = new String[headings.length];
for (int i = 0; i < newRow.length; i++) {
newRow[i] = defaultValue;
}
return newRow;
}
}

JavaFX TableView not updating immediately

I have an issue with JavaFX TableView UI update. After I change the observable object, it does not update the UI of TableView. But if I perform a magical ritual of pulling TableView's scroll bar down and up again - it seems to redraw the table and update items in it.
Through debugging I've ensured, that the PreferencesSet ArrayList and object are updated correctly.
Here's gif demonstration of what is happening
This is my first time asking a question here, so I could have left out some important info. Feel free to ask me for it. Thank you in advance.
Here's code (I have left out unrelated stuff):
ControllerClass:
public class TestSomethingController implements Initializable {
public TableView<PreferenceValues.PreferencesSet> preferencesTable;
public TableColumn mdColumn;
public TableColumn typeColumn;
public TableColumn tradeColumn;
public TableColumn plastColumn;
public TableColumn capColumn;
public TableColumn multColumn;
public TableColumn sizeColumn;
#Override
public void initialize(URL location, ResourceBundle resources) {
setNorthPanel();
setTableColumns();
fillAllInfo();
}
private void setTableColumns() {
mdColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, MarketDirection>("md"));
typeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, UserOfferType>("type"));
tradeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Boolean>("trade"));
plastColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Long>("plast"));
capColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Double>("cap"));
multColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Double>("mult"));
sizeColumn.setCellValueFactory(new PropertyValueFactory<PreferenceValues.PreferencesSet, Long>("size"));
}
private void fillAllInfo() {
preferencesTable.setItems(FXCollections.observableArrayList(CurrentSession.currentUser.getPreferencesList()));
fillNorthPanel();
}
public void applyClicked(ActionEvent actionEvent) {
applyNorthPanelChanges();
}
private void applyNorthPanelChanges() {
PreferenceValues.PreferencesSet preferencesSet = CurrentSession.currentUser.getPreferencesSet(dirChoiceBox.getSelectionModel().getSelectedItem(), offerTypeChoiceBox.getSelectionModel().getSelectedItem());
preferencesSet.setTrade(tradeCheckBox.isSelected());
preferencesSet.setPlast(plastSpinner.getValue());
preferencesSet.setCap(capRateSpinner.getValue());
preferencesSet.setMult(multSpinner.getValue());
preferencesSet.setSize(sizeSpinner.getValue());
preferencesSet.savePreferences();
}
User class:
public class User {
private PreferenceValues preferenceValues;
public PreferenceValues.PreferencesSet getPreferencesSet(MarketDirection md, UserOfferType userOfferType) {
return preferenceValues.getPreferencesSet(md, userOfferType);
}
public ArrayList<PreferenceValues.PreferencesSet> getPreferencesList() {
return preferenceValues.getPreferencesList();
}
}
PreferenceValues class:
import java.util.ArrayList;
import java.util.TreeMap;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
public class PreferenceValues {
private Preferences preferences;
private ArrayList<PreferencesSet> preferencesList;
private TreeMap<String, PreferencesSet> preferencesMap;
public PreferenceValues(User user) {
preferencesList = new ArrayList<>();
preferencesMap = new TreeMap<>();
preferences = Preferences.userRoot().node("prefexample" + user.getwmId());
for (MarketDirection md : MarketDirection.values()) {
for (UserOfferType userOfferType : UserOfferType.values()) {
if (userOfferType != UserOfferType.UNDEF) {
PreferencesSet preferencesSet = new PreferencesSet(md, userOfferType, preferences);
preferencesList.add(preferencesSet);
preferencesMap.put(md.toString() + userOfferType.toString(), preferencesSet);
}
}
}
}
protected ArrayList<PreferencesSet> getPreferencesList() {
return preferencesList;
}
private String getMapKey(MarketDirection md, UserOfferType userOfferType) {
return md.toString() + userOfferType.toString();
}
protected PreferencesSet getPreferencesSet(MarketDirection md, UserOfferType userOfferType) {
return preferencesMap.get(getMapKey(md, userOfferType));
}
public void clear() throws BackingStoreException {
preferences.clear();
}
public class PreferencesSet {
Preferences preferences;
private MarketDirection md;
private UserOfferType type;
private boolean trade;
private int plast;
private double cap;
private double mult;
private int size;
public PreferencesSet(MarketDirection md, UserOfferType type, Preferences preferences) {
this.md = md;
this.type = type;
this.preferences = preferences;
trade = preferences.node(md.toString()).node(type.toString()).getBoolean("trade", false);
plast = preferences.node(md.toString()).node(type.toString()).getInt("plast", 222);
cap = preferences.node(md.toString()).node(type.toString()).getDouble("cap", 333);
mult = preferences.node(md.toString()).node(type.toString()).getDouble("mult", 1);
size = preferences.node(md.toString()).node(type.toString()).getInt("size", 15000);
}
public void savePreferences() {
preferences.node(md.toString()).node(type.toString()).putBoolean("trade", trade);
preferences.node(md.toString()).node(type.toString()).putInt("plast", plast);
preferences.node(md.toString()).node(type.toString()).putDouble("cap", cap);
preferences.node(md.toString()).node(type.toString()).putDouble("mult", mult);
preferences.node(md.toString()).node(type.toString()).putInt("size", size);
}
public MarketDirection getMd() {
return md;
}
public UserOfferType getType() {
return type;
}
public boolean isTrade() {
return trade;
}
public int getPlast() {
return plast;
}
public double getCap() {
return cap;
}
public double getMult() {
return mult;
}
public int getSize() {
return size;
}
public void setTrade(boolean trade) {
this.trade = trade;
}
public void setPlast(int plast) {
this.plast = plast;
}
public void setCap(double cap) {
this.cap = cap;
}
public void setMult(double mult) {
this.mult = mult;
}
public void setSize(int size) {
this.size = size;
}
}
}
Since the only way for PropertyValueFactory to retrieve the value is using the getter, changes of a property cannot be observed and therefore the update only happens, when the item is associated with a new TableRow.
Starting with JavaFX 8u60 you can simply call the refresh method of TableView, which will force an update to be executed.
However the usual way of doing this is by providing access to a property object containing the property value, e.g.
In PreferencesSet
private final IntegerProperty plast = new SimpleIntegerProperty();
public void setPlast(int plast) {
this.plast.set(plast);
}
public int getPlast() {
return plast.get();
}
// this method will be used by the PropertyValueFactory
// and returns a Property which notifies TableView of changes
public IntegerProperty plastProperty() {
return plast;
}
There are other property types for the other data types, see javafx.beans.property package

How to sort an array that is combined by "null" and Strings?

I have got an array of 20:
private Karte[] deckArr;
deckArr = new Karte[20];
Now I want to sort the array by card-names every time a new card is added.
P.S. the cards are added 1 by 1 after clicking on a button, so there are empty spaces in the array.
Since the...
Arrays.sort(deckArr.getName());
...method does not work here I asked myself how it is done.
Karte(card) class:
package Model;
/**
* Created by 204g07 on 18.03.2016.
*/
public class Karte implements ComparableContent<Karte>{
private int schoenheit;
private int staerke;
private int geschwindigkeit;
private int intelligenz;
private int coolness;
private int alter;
private String seltenheit;
private String name;
public Karte(String pName, int pSchoenheit,int pStaerke,int pGeschwindigkeit, int pIntelligenz, int pCoolness, int pAlter, String pSeltenheit ) {
name=pName;
schoenheit=pSchoenheit;
staerke=pStaerke;
geschwindigkeit=pGeschwindigkeit;
intelligenz=pIntelligenz;
coolness=pCoolness;
alter=pAlter;
seltenheit=pSeltenheit;
}
//getter
public int getSchoenheit(){
return schoenheit;
}
public int getStaerke(){
return staerke;
}
public int getGeschwindigkeit(){
return geschwindigkeit;
}
public int getIntelligenz(){
return intelligenz;
}
public int getCoolness(){
return coolness;
}
public int getAlter(){
return alter;
}
public String getSeltenheit(){
return seltenheit;
}
public String getName(){
return name;
}
//setter
public void setSchoenheit(int pSchoenheit){
schoenheit = pSchoenheit;
}
public void setStaerke(int pStaerke){
staerke = pStaerke;
}
public void setGeschwindigkeit(int pGeschwindigkeit){
geschwindigkeit = pGeschwindigkeit;
}
public void setIntelligenz(int pIntelligenz){
intelligenz = pIntelligenz;
}
public void setCoolness(int pCoolness){
coolness = pCoolness;
}
public void setAlter(int pAlter){
alter = pAlter;
}
public void setSeltenheit(String pSeltenheit){
seltenheit = pSeltenheit;
}
public void setName(String pName){
name = pName;
}
#Override
public boolean isLess(Karte karte) {
if (getName().compareTo(karte.getName()) < 0){
return true;
}else{
return false;
}
}
#Override
public boolean isEqual(Karte karte) {
return getName() == karte.getName();
}
#Override
public boolean isGreater(Karte karte) {
if (getName().compareTo(karte.getName()) > 0){
return true;
}else{
return false;
}
}
}
Any help is appreciated!
Why not just use ArrayList instead? Easier to add, remove elements and you will never have empty slots.
Anyway to sort you can use Collections.sort like this:
deckArr = new ArrayList<Karte>();
Collections.sort(deckArr, Comparator.comparing(karte -> karte.getName()));
Java 8 offers a simple solution:
The Comparable Interface has a static method that creates a Comaprator with an extractor.
Comparator<Card> comp = Comparator.comparing(Karte::getName);
With this using a sorting method (e.g. Arrays.sort) is easy to call.
On top of that, to solve your nullpointer problem, the Comparator Interface offers another two functions: NullsLast and nullsFirst.
Comparator<Card> comp = Comparator.nullsLast(Comparator.comparing(Card::getName));
For me this looks like the easiest solution to your question :)
This should solve your problem. Implements the Comparable interface.
/**
* Created by 204g07 on 18.03.2016.
*/
public class Karte implements Comparable<Karte>{
private int schoenheit;
private int staerke;
private int geschwindigkeit;
private int intelligenz;
private int coolness;
private int alter;
private String seltenheit;
private String name;
public Karte(String pName, int pSchoenheit,int pStaerke,int pGeschwindigkeit, int pIntelligenz, int pCoolness, int pAlter, String pSeltenheit ) {
name=pName;
schoenheit=pSchoenheit;
staerke=pStaerke;
geschwindigkeit=pGeschwindigkeit;
intelligenz=pIntelligenz;
coolness=pCoolness;
alter=pAlter;
seltenheit=pSeltenheit;
}
//getter
public int getSchoenheit(){
return schoenheit;
}
public int getStaerke(){
return staerke;
}
public int getGeschwindigkeit(){
return geschwindigkeit;
}
public int getIntelligenz(){
return intelligenz;
}
public int getCoolness(){
return coolness;
}
public int getAlter(){
return alter;
}
public String getSeltenheit(){
return seltenheit;
}
public String getName(){
return name;
}
//setter
public void setSchoenheit(int pSchoenheit){
schoenheit = pSchoenheit;
}
public void setStaerke(int pStaerke){
staerke = pStaerke;
}
public void setGeschwindigkeit(int pGeschwindigkeit){
geschwindigkeit = pGeschwindigkeit;
}
public void setIntelligenz(int pIntelligenz){
intelligenz = pIntelligenz;
}
public void setCoolness(int pCoolness){
coolness = pCoolness;
}
public void setAlter(int pAlter){
alter = pAlter;
}
public void setSeltenheit(String pSeltenheit){
seltenheit = pSeltenheit;
}
public void setName(String pName){
name = pName;
}
public int compareTo(Karte karte) {
return this.name.compareTo(karte.getName());
}
}
Then you just need to call Arrays.sort(deckArr);
You need to check for nulls and just call below--
Arrays.sort(deckArr, new Comparator<Karte>() {
#Override
public int compare(Karte karte1, Karte karte2) {
if (karte1.getName() == null && karte2.getName() == null) {
return 0;
}
if (karte1.getName() == null) {
return 1;
}
if (karte2.getName() == null) {
return -1;
}
return karte1.getName().compareTo(karte2.getName());
}});

Confusion on using instanceof along with other inherited data

I have already made a posting about this program once, but I am once again stuck on a new concept that I am learning (Also as a side note; I am a CS student so please DO NOT simply hand me a solution, for my University has strict code copying rules, thank you.). There are a couple of difficulties I am having with this concept, the main one being that I am having a hard time implementing it to my purposes, despite the textbook examples making perfect sense. So just a quick explanation of what I'm doing:
I have an entity class that takes a Scanner from a driver. My other class then hands off the scanner to a superclass and its two subclasses then inherit that scanner. Each class has different data from the .txt the Scanner read through. Then those three classes send off their data to the entity to do final calculations. And that is where my problem lies, after all the data has been read. I have a method that displays a new output along with a few methods that add data from the super along with its derived classes.EDIT: I simply cannot figure out how to call the instance variable of my subclasses through the super so I can add and calculate the data.
Here are my four classes in the order; Driver, Entity, Super, Subs:
public static final String INPUT_FILE = "baseballTeam.txt";
public static void main(String[] args) {
BaseballTeam team = new BaseballTeam();
Scanner inFile = null;
try {
inFile = new Scanner(new File(INPUT_FILE));
team.loadTeam(inFile);
team.outputTeam();
} catch (FileNotFoundException e) {
System.out.println("File " + INPUT_FILE + " Not Found.");
System.exit(1);
}
}
}
public class BaseballTeam {
private String name;
private Player[] roster = new Player[25];
Player pitcher = new Pitcher();
Player batter = new Batter();
BaseballTeam() {
name = "";
}
public String getName() {
return name;
}
public void setName(String aName) {
name = aName;
}
public void loadTeam(Scanner input) {
name = input.nextLine();
for (int i = 0; i < roster.length; i++) {
if (i <= 9) {
roster[i] = new Pitcher();
}
else if ((i > 9) && (i <= 19)) {
roster[i] = new Batter();
}
else if (i > 19) {
roster[i] = new Player();
}
roster[i].loadData(input);
roster[i].generateDisplayString();
//System.out.println(roster[i].generateDisplayString()); //used sout to test for correct data
}
}
public void outputTeam() {
if ((pitcher instanceof Player) && (batter instanceof Player)) {
for (int i = 0; i < roster.length; i++) {
System.out.println(roster[i].generateDisplayString());
}
}
//How do I go about doing calculates?
public int calculateTeamWins() {
if ((pitcher instanceof ) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamSaves() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamERA() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamWHIP() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamBattingAverage() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamHomeRuns() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamRBI() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateStolenBases() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
}
public class Player {
protected String name;
protected String position;
Player(){
name = "";
position = "";
}
public String getName() {
return name;
}
public void setName(String aName) {
name = aName;
}
public String getPosition() {
return position;
}
public void setPosition(String aPosition) {
position = aPosition;
}
public void loadData(Scanner input){
do {
name = input.nextLine();
} while (name.equals(""));
position = input.next();
//System.out.println(generateDisplayString());
}
public String generateDisplayString(){
return "Name: " + name + ", Position:" + position;
}
}
public class Pitcher extends Player {
private int wins;
private int saves;
private int inningsPitched;
private int earnedRuns;
private int hits;
private int walks;
private double ERA;
private double WHIP;
Pitcher() {
super();
wins = 0;
saves = 0;
inningsPitched = 0;
earnedRuns = 0;
hits = 0;
walks = 0;
}
public int getWins() {
return wins;
}
public void setWins(int aWins) {
wins = aWins;
}
public int getSaves() {
return saves;
}
public void setSaves(int aSaves) {
saves = aSaves;
}
public int getInningsPitched() {
return inningsPitched;
}
public void setInningsPitched(int aInningsPitched) {
inningsPitched = aInningsPitched;
}
public int getEarnedRuns() {
return earnedRuns;
}
public void setEarnedRuns(int aEarnedRuns) {
earnedRuns = aEarnedRuns;
}
public int getHits() {
return hits;
}
public void setHits(int aHits) {
hits = aHits;
}
public int getWalks() {
return walks;
}
public void setWalks(int aWalks) {
walks = aWalks;
}
#Override
public void loadData(Scanner input) {
super.loadData(input);
wins = input.nextInt();
saves = input.nextInt();
inningsPitched = input.nextInt();
earnedRuns = input.nextInt();
hits = input.nextInt();
walks = input.nextInt();
}
#Override
public String generateDisplayString() {
calculateERA();
calculateWHIP();
return String.format(super.generateDisplayString() + ", Wins:%1d, Saves:%1d,"
+ " ERA:%1.2f, WHIP:%1.3f ", wins, saves, ERA, WHIP);
}
public double calculateERA() {
try {
ERA = ((double)(earnedRuns * 9) / inningsPitched);
} catch (ArithmeticException e) {
ERA = 0;
}
return ERA;
}
public double calculateWHIP() {
try {
WHIP = ((double)(walks + hits) / inningsPitched);
} catch (ArithmeticException e) {
WHIP = 0;
}
return WHIP;
}
}
public class Batter extends Player {
private int atBats;
private int hits;
private int homeRuns;
private int rbi;
private int stolenBases;
private double batAvg;
Batter() {
super();
atBats = 0;
hits = 0;
homeRuns = 0;
rbi = 0;
stolenBases = 0;
}
public int getAtBats() {
return atBats;
}
public void setAtBats(int aAtBats) {
atBats = aAtBats;
}
public int getHits() {
return hits;
}
public void setHits(int aHits) {
hits = aHits;
}
public int getHomeRuns() {
return homeRuns;
}
public void setHomeRuns(int aHomeRuns) {
homeRuns = aHomeRuns;
}
public int getRbi() {
return rbi;
}
public void setRbi(int aRbi) {
rbi = aRbi;
}
public int getStolenBases() {
return stolenBases;
}
public void setStolenBases(int aStolenBases) {
stolenBases = aStolenBases;
}
#Override
public void loadData(Scanner input) {
super.loadData(input);
atBats = input.nextInt();
hits = input.nextInt();
homeRuns = input.nextInt();
rbi = input.nextInt();
stolenBases = input.nextInt();
}
#Override
public String generateDisplayString() {
calculateBattingAverage();
return String.format(super.generateDisplayString() +
", Batting Average:%1.3f, Home Runs:%1d, RBI:%1d, Stolen Bases:%1d"
, batAvg, homeRuns, rbi, stolenBases);
}
public double calculateBattingAverage() {
try{
batAvg = ((double)hits/atBats);
} catch (ArithmeticException e){
batAvg = 0;
}
return batAvg;
}
}
Also, its probably easy to tell I'm still fairly new here, because I just ran all my classes together in with the code sample and I can't figure out to add the gaps, so feel free to edit if need be.
The typical usage of instanceof in the type of scenario you're describing would be
if (foo instanceof FooSubclass) {
FooSubclass fooSub = (FooSubclass) foo;
//foo and fooSub now are references to the same object, and you can use fooSub to call methods on the subclass
} else if (foo instanceof OtherSubclass) {
OtherSubclass otherSub = (OtherSubclass) foo;
//you can now use otherSub to call subclass-specific methods on foo
}
This is called "casting" or "explicitly casting" foo to FooSubclass.
the concept to call the methods of your subclasses is called polymorphism.
In your runtime the most specific available method is called provided that the method names are the same.
so you can
Superclass class = new Subclass();
class.method();
and the method provided that overwrites the method in Superclass will be called, even if it's defined in the Subclass.
Sorry for my english, I hope that helps a little bit ;-)

JTable display data in arrayList

coding in Java Eclipse here. Making a booking system. The idea is to take the info from the database ,store it in the ArrayList and from the ArrayList show it in the GUI through JTable. Having some problems with the last part and just can't figure it out..
ArrayList:
import java.util.ArrayList;
public class CarList
{
private ArrayList<Car> cars;
public CarList()
{
cars = new ArrayList<Car>();
}
public int getNumberOfCars()
{
return cars.size();
}
public Car getCar(String CarMake)
{
for (int i = 0; i < cars.size(); i++)
{
if (cars.get(i).getMake() == CarMake)
{
return cars.get(i);
}
}
return null;
}
public int size()
{
return cars.size();
}
public void add(Car car)
{
if (!this.ModelExists(car.getModel()))
{
cars.add(car);
}
}
public Boolean ModelExists(String Model)
{
for (Car c : cars)
{
if (c.getModel().equals(Model))
{
return true;
}
}
return false;
}
public void remove(String CarMake)
{
for (int i = 0; i < cars.size(); i++)
{
if (cars.get(i).getMake() == CarMake)
{
cars.remove(i);
}
}
}
public String toString()
{
String returnStr = "";
for (int i = 0; i < cars.size(); i++)
{
Car temp = cars.get(i);
returnStr += temp + "\n";
}
return returnStr;
}
}
Adapter to get the data from the db to the arraylist:
public CarList getAllCars()
{
MyDatabase myDB = new MyDatabase();
CarList cars = new CarList();
try
{
myDB.openMySQLDatabase("db", "root", "");
String sql = "SELECT Make, Model, LicenseNumber, Color, Year," +
"HorsePower, TimeUntilService, ConsumptionPerKm," +
"NumberOfSeats, NumberOfDoors, Transmission, ClimateControl,Price "
+ "FROM cars";
System.out.println(sql);
Object[][] result = myDB.returnSQLQueryResult(sql);
for (int rows = 0; rows < result.length; rows++)
{
System.out.println("result row");
String make = (String) result[rows][0];
String model = (String) result[rows][1];
String licenseNumber = (String) result[rows][2];
String color = (String) result[rows][3];
int year = (int) result[rows][4];
String horsePower = (String) result[rows][5];
String timeUntilService = (String) result[rows][6];
String consumptionPerKm = (String) result[rows][7];
int numberOfSeats = (int) result[rows][8];
int numberOfDoors = (int) result[rows][9];
String transmission = (String) result[rows][10];
String climateControl = (String) result[rows][11];
int price = (int) result[rows][12];
cars.add(new Car(make, model, licenseNumber, color, year, horsePower,
timeUntilService, consumptionPerKm, climateControl, numberOfSeats, numberOfDoors, transmission, climateControl, price));
}
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
finally
{
try
{
myDB.closeDatabase();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
System.out.println(cars.size());
return cars;
}
JTable:
panelBottomRight = new JPanel();
panelBottomRight.setLayout(new BorderLayout());
panelBottomRight.setBorder(new TitledBorder(BorderFactory
.createLineBorder(Color.black), "[Cars]", 2, 0));
tableBottomRightCenter = new JPanel();
tableBottomRightCenter.setLayout(new BorderLayout());
String[] columnNames = { "Make", "Model", "LicenseNumber", "Color",
"Year", "HorsePower", "TimeUntilService",
"ConsumptionPerKm", "NumberOfSeats", "NumberOfDoors",
"ClimateControl" };
CarList cars= new CarList();
String[][] data = {};
// Create table with database data
tableBottomR = new JTable(data, columnNames);
tableBottomR.setAutoCreateRowSorter(true);
tableBottomR.getTableHeader().setReorderingAllowed(false);
tableBottomR.setModel(new DefaultTableModel(data, columnNames)
{
#Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return false;
}
});
tableBottomRightCenter.add(tableBottomR, BorderLayout.CENTER);
scrollPane2 = new JScrollPane(tableBottomR);
scrollPane2
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
tableBottomRightCenter.add(scrollPane2);
panelBottomRight.add(tableBottomRightCenter, BorderLayout.CENTER);
There are a few things that jump out.
In you CarList, the getCar method is comparing object references instead of comparing the contents of the String
For String comparison, you should be using String#equals, for example...
public Car getCar(String CarMake) {
for (int i = 0; i < cars.size(); i++) {
//if (cars.get(i).getMake() == CarMake) {
if (cars.get(i).getMake().equals(CarMake)) {
return cars.get(i);
}
}
return null;
}
You don't seem to be using the getAllCars method to populate the table model, but are simply creating a series of empty table models.
Personally, I'm not a fan of DefaultTableModel, especially given the fact that you have a Car object and CarList object, i would require you to undo all this work to use it, instead, I prefer to create my own, specialised, implementation, which allows me to provide greater control, for example...
public class CarModel extends AbstractTableModel {
private String[] columnNames = { "Make", "Model", "LicenseNumber", "Color",
"Year", "HorsePower", "TimeUntilService",
"ConsumptionPerKm", "NumberOfSeats", "NumberOfDoors",
"ClimateControl" };
private CarList carList;
public CarModel(CarList list) {
carList = list;
}
public CarList getCarList() {
return carList;
}
#Override
public int getRowCount() {
return getCarList().getNumberOfCars();
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public String getColumnName(int column) {
return columnNames[column];
}
#Override
public Class<?> getColumnClass(int columnIndex) {
Class type = String.class;
switch (columnIndex) {
case 0:
type = String.class;
break;
// ...etc...
}
return type;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Car car = getCarList().getCarAt(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = car.getMake();
break;
//...etc...
}
return value;
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
}
This, obviously, will require you to add a getCarAt(int) method to your CarList to return the Car at the given index.
Then, you simply need to extract the data from the database and apply the resulting CarList to the table model, for example...
CarList carList = getAllCars();
CarTableModel model = new CarTableModel(carList);
Then, you just need to add it to your UI, for example...
JTable table = new JTable(model);
add(new JScrollPane(table));
Take a look at How to use tables for more details and examples...

Categories

Resources